﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
  
// Include Silverlight's managed resources
#if SILVERLIGHT
using System.Core;
#endif //SILVERLIGHT
  
namespace System.Linq
{
    public static class Enumerable
    {
        public static IEnumerable<tsource> Where<tsource>(this IEnumerable<tsource> source, Func<tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            if (source is Iterator<tsource>) return ((Iterator<tsource>)source).Where(predicate);
            if (source is TSource[]) return new WhereArrayIterator<tsource>((TSource[])source, predicate);
            if (source is List<tsource>) return new WhereListIterator<tsource>((List<tsource>)source, predicate);
            return new WhereEnumerableIterator<tsource>(source, predicate);
        }
  
        public static IEnumerable<tsource> Where<tsource>(this IEnumerable<tsource> source, Func<tsource, int,="" bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            return WhereIterator<tsource>(source, predicate);
        }
 
        static IEnumerable<tsource> WhereIterator<tsource>(IEnumerable<tsource> source, Func<tsource, int,="" bool=""> predicate) {
            int index = -1;
            foreach (TSource element in source) {
                checked { index++; }
                if (predicate(element, index)) yield return element;
            }
        }
  
        public static IEnumerable<tresult> Select<tsource, tresult="">(this IEnumerable<tsource> source, Func<tsource, tresult=""> selector) {
            if (source == null) throw Error.ArgumentNull("source");
            if (selector == null) throw Error.ArgumentNull("selector");
            if (source is Iterator<tsource>) return ((Iterator<tsource>)source).Select(selector);
            if (source is TSource[]) return new WhereSelectArrayIterator<tsource, tresult="">((TSource[])source, null, selector);
            if (source is List<tsource>) return new WhereSelectListIterator<tsource, tresult="">((List<tsource>)source, null, selector);
            return new WhereSelectEnumerableIterator<tsource, tresult="">(source, null, selector);
        }
  
        public static IEnumerable<tresult> Select<tsource, tresult="">(this IEnumerable<tsource> source, Func<tsource, int,="" tresult=""> selector) {
            if (source == null) throw Error.ArgumentNull("source");
            if (selector == null) throw Error.ArgumentNull("selector");
            return SelectIterator<tsource, tresult="">(source, selector);
        }
  
        static IEnumerable<tresult> SelectIterator<tsource, tresult="">(IEnumerable<tsource> source, Func<tsource, int,="" tresult=""> selector) {
            int index = -1;
            foreach (TSource element in source) {
                checked { index++; }
                yield return selector(element, index);
            }
        }
 
        static Func<tsource, bool=""> CombinePredicates<tsource>(Func<tsource, bool=""> predicate1, Func<tsource, bool=""> predicate2) {
            return x => predicate1(x) && predicate2(x);
        }
  
        static Func<tsource, tresult=""> CombineSelectors<tsource, tmiddle,="" tresult="">(Func<tsource, tmiddle=""> selector1, Func<tmiddle, tresult=""> selector2) {
            return x => selector2(selector1(x));
        }
  
        abstract class Iterator<tsource> : IEnumerable<tsource>, IEnumerator<tsource>
        {
            int threadId;
            internal int state;
            internal TSource current;
 
            public Iterator() {
                threadId = Thread.CurrentThread.ManagedThreadId;
            }
 
            public TSource Current {
                get { return current; }
            }
  
            public abstract Iterator<tsource> Clone();
 
            public virtual void Dispose() {
                current = default(TSource);
                state = -1;
            }
  
            public IEnumerator<tsource> GetEnumerator() {
                if (threadId == Thread.CurrentThread.ManagedThreadId && state == 0) {
                    state = 1;
                    return this;
                }
                Iterator<tsource> duplicate = Clone();
                duplicate.state = 1;
                return duplicate;
            }
 
            public abstract bool MoveNext();
 
            public abstract IEnumerable<tresult> Select<tresult>(Func<tsource, tresult=""> selector);
 
            public abstract IEnumerable<tsource> Where(Func<tsource, bool=""> predicate);
 
            object IEnumerator.Current {
                get { return Current; }
            }
  
            IEnumerator IEnumerable.GetEnumerator() {
                return GetEnumerator();
            }
  
            void IEnumerator.Reset() {
                throw new NotImplementedException();
            }
        }
  
        class WhereEnumerableIterator<tsource> : Iterator<tsource>
        {
            IEnumerable<tsource> source;
            Func<tsource, bool=""> predicate;
            IEnumerator<tsource> enumerator;
  
            public WhereEnumerableIterator(IEnumerable<tsource> source, Func<tsource, bool=""> predicate) {
                this.source = source;
                this.predicate = predicate;
            }
 
            public override Iterator<tsource> Clone() {
                return new WhereEnumerableIterator<tsource>(source, predicate);
            }
  
            public override void Dispose() {
                if (enumerator is IDisposable) ((IDisposable)enumerator).Dispose();
                enumerator = null;
                base.Dispose();
            }
 
            public override bool MoveNext() {
                switch (state) {
                    case 1:
                        enumerator = source.GetEnumerator();
                        state = 2;
                        goto case 2;
                    case 2:
                        while (enumerator.MoveNext()) {
                            TSource item = enumerator.Current;
                            if (predicate(item)) {
                                current = item;
                                return true;
                            }
                        }
                        Dispose();
                        break;
                }
                return false;
            }
 
            public override IEnumerable<tresult> Select<tresult>(Func<tsource, tresult=""> selector) {
                return new WhereSelectEnumerableIterator<tsource, tresult="">(source, predicate, selector);
            }
  
            public override IEnumerable<tsource> Where(Func<tsource, bool=""> predicate) {
                return new WhereEnumerableIterator<tsource>(source, CombinePredicates(this.predicate, predicate));
            }
        }
 
        class WhereArrayIterator<tsource> : Iterator<tsource>
        {
            TSource[] source;
            Func<tsource, bool=""> predicate;
            int index;
 
            public WhereArrayIterator(TSource[] source, Func<tsource, bool=""> predicate) {
                this.source = source;
                this.predicate = predicate;
            }
  
            public override Iterator<tsource> Clone() {
                return new WhereArrayIterator<tsource>(source, predicate);
            }
 
            public override bool MoveNext() {
                if (state == 1) {
                    while (index < source.Length) {
                        TSource item = source[index];
                        index++;
                        if (predicate(item)) {
                            current = item;
                            return true;
                        }
                    }
                    Dispose();
                }
                return false;
            }
 
            public override IEnumerable<tresult> Select<tresult>(Func<tsource, tresult=""> selector) {
                return new WhereSelectArrayIterator<tsource, tresult="">(source, predicate, selector);
            }
 
            public override IEnumerable<tsource> Where(Func<tsource, bool=""> predicate) {
                return new WhereArrayIterator<tsource>(source, CombinePredicates(this.predicate, predicate));
            }
        }
 
        class WhereListIterator<tsource> : Iterator<tsource>
        {
            List<tsource> source;
            Func<tsource, bool=""> predicate;
            List<tsource>.Enumerator enumerator;
 
            public WhereListIterator(List<tsource> source, Func<tsource, bool=""> predicate) {
                this.source = source;
                this.predicate = predicate;
            }
 
            public override Iterator<tsource> Clone() {
                return new WhereListIterator<tsource>(source, predicate);
            }
 
            public override bool MoveNext() {
                switch (state) {
                    case 1:
                        enumerator = source.GetEnumerator();
                        state = 2;
                        goto case 2;
                    case 2:
                        while (enumerator.MoveNext()) {
                            TSource item = enumerator.Current;
                            if (predicate(item)) {
                                current = item;
                                return true;
                            }
                        }
                        Dispose();
                        break;
                }
                return false;
            }
  
            public override IEnumerable<tresult> Select<tresult>(Func<tsource, tresult=""> selector) {
                return new WhereSelectListIterator<tsource, tresult="">(source, predicate, selector);
            }
 
            public override IEnumerable<tsource> Where(Func<tsource, bool=""> predicate) {
                return new WhereListIterator<tsource>(source, CombinePredicates(this.predicate, predicate));
            }
        }
  
        class WhereSelectEnumerableIterator<tsource, tresult=""> : Iterator<tresult>
        {
            IEnumerable<tsource> source;
            Func<tsource, bool=""> predicate;
            Func<tsource, tresult=""> selector;
            IEnumerator<tsource> enumerator;
 
            public WhereSelectEnumerableIterator(IEnumerable<tsource> source, Func<tsource, bool=""> predicate, Func<tsource, tresult=""> selector) {
                this.source = source;
                this.predicate = predicate;
                this.selector = selector;
            }
 
            public override Iterator<tresult> Clone() {
                return new WhereSelectEnumerableIterator<tsource, tresult="">(source, predicate, selector);
            }
  
            public override void Dispose() {
                if (enumerator is IDisposable) ((IDisposable)enumerator).Dispose();
                enumerator = null;
                base.Dispose();
            }
 
            public override bool MoveNext() {
                switch (state) {
                    case 1:
                        enumerator = source.GetEnumerator();
                        state = 2;
                        goto case 2;
                    case 2:
                        while (enumerator.MoveNext()) {
                            TSource item = enumerator.Current;
                            if (predicate == null || predicate(item)) {
                                current = selector(item);
                                return true;
                            }
                        }
                        Dispose();
                        break;
                }
                return false;
            }
 
            public override IEnumerable<tresult2> Select<tresult2>(Func<tresult, tresult2=""> selector) {
                return new WhereSelectEnumerableIterator<tsource, tresult2="">(source, predicate, CombineSelectors(this.selector, selector));
            }
  
            public override IEnumerable<tresult> Where(Func<tresult, bool=""> predicate) {
                return new WhereEnumerableIterator<tresult>(this, predicate);
            }
        }
 
        class WhereSelectArrayIterator<tsource, tresult=""> : Iterator<tresult>
        {
            TSource[] source;
            Func<tsource, bool=""> predicate;
            Func<tsource, tresult=""> selector;
            int index;
 
            public WhereSelectArrayIterator(TSource[] source, Func<tsource, bool=""> predicate, Func<tsource, tresult=""> selector) {
                this.source = source;
                this.predicate = predicate;
                this.selector = selector;
            }
  
            public override Iterator<tresult> Clone() {
                return new WhereSelectArrayIterator<tsource, tresult="">(source, predicate, selector);
            }
  
            public override bool MoveNext() {
                if (state == 1) {
                    while (index < source.Length) {
                        TSource item = source[index];
                        index++;
                        if (predicate == null || predicate(item)) {
                            current = selector(item);
                            return true;
                        }
                    }
                    Dispose();
                }
                return false;
            }
 
            public override IEnumerable<tresult2> Select<tresult2>(Func<tresult, tresult2=""> selector) {
                return new WhereSelectArrayIterator<tsource, tresult2="">(source, predicate, CombineSelectors(this.selector, selector));
            }
 
            public override IEnumerable<tresult> Where(Func<tresult, bool=""> predicate) {
                return new WhereEnumerableIterator<tresult>(this, predicate);
            }
        }
 
        class WhereSelectListIterator<tsource, tresult=""> : Iterator<tresult>
        {
            List<tsource> source;
            Func<tsource, bool=""> predicate;
            Func<tsource, tresult=""> selector;
            List<tsource>.Enumerator enumerator;
 
            public WhereSelectListIterator(List<tsource> source, Func<tsource, bool=""> predicate, Func<tsource, tresult=""> selector) {
                this.source = source;
                this.predicate = predicate;
                this.selector = selector;
            }
 
            public override Iterator<tresult> Clone() {
                return new WhereSelectListIterator<tsource, tresult="">(source, predicate, selector);
            }
  
            public override bool MoveNext() {
                switch (state) {
                    case 1:
                        enumerator = source.GetEnumerator();
                        state = 2;
                        goto case 2;
                    case 2:
                        while (enumerator.MoveNext()) {
                            TSource item = enumerator.Current;
                            if (predicate == null || predicate(item)) {
                                current = selector(item);
                                return true;
                            }
                        }
                        Dispose();
                        break;
                }
                return false;
            }
 
            public override IEnumerable<tresult2> Select<tresult2>(Func<tresult, tresult2=""> selector) {
                return new WhereSelectListIterator<tsource, tresult2="">(source, predicate, CombineSelectors(this.selector, selector));
            }
  
            public override IEnumerable<tresult> Where(Func<tresult, bool=""> predicate) {
                return new WhereEnumerableIterator<tresult>(this, predicate);
            }
        }
 
        //public static IEnumerable<tsource> Where<tsource>(this IEnumerable<tsource> source, Func<tsource, bool=""> predicate) {
        //    if (source == null) throw Error.ArgumentNull("source");
        //    if (predicate == null) throw Error.ArgumentNull("predicate");
        //    return WhereIterator<tsource>(source, predicate);
        //}
 
        //static IEnumerable<tsource> WhereIterator<tsource>(IEnumerable<tsource> source, Func<tsource, bool=""> predicate) {
        //    foreach (TSource element in source) {
        //        if (predicate(element)) yield return element;
        //    }
        //}
 
        //public static IEnumerable<tresult> Select<tsource, tresult="">(this IEnumerable<tsource> source, Func<tsource, tresult=""> selector) {
        //    if (source == null) throw Error.ArgumentNull("source");
        //    if (selector == null) throw Error.ArgumentNull("selector");
        //    return SelectIterator<tsource, tresult="">(source, selector);
        //}
 
        //static IEnumerable<tresult> SelectIterator<tsource, tresult="">(IEnumerable<tsource> source, Func<tsource, tresult=""> selector) {
        //    foreach (TSource element in source) {
        //        yield return selector(element);
        //    }
        //}
 
        public static IEnumerable<tresult> SelectMany<tsource, tresult="">(this IEnumerable<tsource> source, Func<tsource, ienumerable<tresult="">> selector) {
            if (source == null) throw Error.ArgumentNull("source");
            if (selector == null) throw Error.ArgumentNull("selector");
            return SelectManyIterator<tsource, tresult="">(source, selector);
        }
 
        static IEnumerable<tresult> SelectManyIterator<tsource, tresult="">(IEnumerable<tsource> source, Func<tsource, ienumerable<tresult="">> selector) {
            foreach (TSource element in source) {
                foreach (TResult subElement in selector(element)) {
                    yield return subElement;
                }
            }
        }
  
        public static IEnumerable<tresult> SelectMany<tsource, tresult="">(this IEnumerable<tsource> source, Func<tsource, int,="" ienumerable<tresult="">> selector) {
            if (source == null) throw Error.ArgumentNull("source");
            if (selector == null) throw Error.ArgumentNull("selector");
            return SelectManyIterator<tsource, tresult="">(source, selector);
        }
 
        static IEnumerable<tresult> SelectManyIterator<tsource, tresult="">(IEnumerable<tsource> source, Func<tsource, int,="" ienumerable<tresult="">> selector) {
            int index = -1;
            foreach (TSource element in source) {
                checked { index++; }
                foreach (TResult subElement in selector(element, index)) {
                    yield return subElement;
                }
            }
        }
        public static IEnumerable<tresult> SelectMany<tsource, tcollection,="" tresult="">(this IEnumerable<tsource> source, Func<tsource, int,="" ienumerable<tcollection="">> collectionSelector, Func<tsource, tcollection,="" tresult=""> resultSelector)
        {
            if (source == null) throw Error.ArgumentNull("source");
            if (collectionSelector == null) throw Error.ArgumentNull("collectionSelector");
            if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
            return SelectManyIterator<tsource, tcollection,="" tresult="">(source, collectionSelector, resultSelector);
        }
  
        static IEnumerable<tresult> SelectManyIterator<tsource, tcollection,="" tresult="">(IEnumerable<tsource> source, Func<tsource, int,="" ienumerable<tcollection="">> collectionSelector, Func<tsource, tcollection,="" tresult=""> resultSelector){
            int index = -1;
            foreach (TSource element in source){
                checked { index++; }
                foreach (TCollection subElement in collectionSelector(element, index)){
                    yield return resultSelector(element, subElement);
                }
            }
        }
 
        public static IEnumerable<tresult> SelectMany<tsource, tcollection,="" tresult="">(this IEnumerable<tsource> source, Func<tsource, ienumerable<tcollection="">> collectionSelector, Func<tsource, tcollection,="" tresult=""> resultSelector) {
            if (source == null) throw Error.ArgumentNull("source");
            if (collectionSelector == null) throw Error.ArgumentNull("collectionSelector");
            if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
            return SelectManyIterator<tsource, tcollection,="" tresult="">(source, collectionSelector, resultSelector);
        }
 
        static IEnumerable<tresult> SelectManyIterator<tsource, tcollection,="" tresult="">(IEnumerable<tsource> source, Func<tsource, ienumerable<tcollection="">> collectionSelector, Func<tsource, tcollection,="" tresult=""> resultSelector) {
            foreach (TSource element in source) {
                foreach (TCollection subElement in collectionSelector(element)) {
                    yield return resultSelector(element, subElement);
                }
            }
        }
  
        public static IEnumerable<tsource> Take<tsource>(this IEnumerable<tsource> source, int count) {
            if (source == null) throw Error.ArgumentNull("source");
            return TakeIterator<tsource>(source, count);
        }
 
        static IEnumerable<tsource> TakeIterator<tsource>(IEnumerable<tsource> source, int count) {
            if (count > 0) {
                foreach (TSource element in source) {
                    yield return element;
                    if (--count == 0) break;
                }
            }
        }
 
        public static IEnumerable<tsource> TakeWhile<tsource>(this IEnumerable<tsource> source, Func<tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            return TakeWhileIterator<tsource>(source, predicate);
        }
  
        static IEnumerable<tsource> TakeWhileIterator<tsource>(IEnumerable<tsource> source, Func<tsource, bool=""> predicate) {
            foreach (TSource element in source) {
                if (!predicate(element)) break;
                yield return element;
            }
        }
  
        public static IEnumerable<tsource> TakeWhile<tsource>(this IEnumerable<tsource> source, Func<tsource, int,="" bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            return TakeWhileIterator<tsource>(source, predicate);
        }
  
        static IEnumerable<tsource> TakeWhileIterator<tsource>(IEnumerable<tsource> source, Func<tsource, int,="" bool=""> predicate) {
            int index = -1;
            foreach (TSource element in source) {
                checked { index++; }
                if (!predicate(element, index)) break;
                yield return element;
            }
        }
  
        public static IEnumerable<tsource> Skip<tsource>(this IEnumerable<tsource> source, int count) {
            if (source == null) throw Error.ArgumentNull("source");
            return SkipIterator<tsource>(source, count);
        }
  
        static IEnumerable<tsource> SkipIterator<tsource>(IEnumerable<tsource> source, int count) {
            using (IEnumerator<tsource> e = source.GetEnumerator()) {
                while (count > 0 && e.MoveNext()) count--;
                if (count <= 0) {
                    while (e.MoveNext()) yield return e.Current;
                }
            }
        }
  
        public static IEnumerable<tsource> SkipWhile<tsource>(this IEnumerable<tsource> source, Func<tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            return SkipWhileIterator<tsource>(source, predicate);
        }
  
        static IEnumerable<tsource> SkipWhileIterator<tsource>(IEnumerable<tsource> source, Func<tsource, bool=""> predicate) {
            bool yielding = false;
            foreach (TSource element in source) {
                if (!yielding && !predicate(element)) yielding = true;
                if (yielding) yield return element;
            }
        }
 
        public static IEnumerable<tsource> SkipWhile<tsource>(this IEnumerable<tsource> source, Func<tsource, int,="" bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            return SkipWhileIterator<tsource>(source, predicate);
        }
 
        static IEnumerable<tsource> SkipWhileIterator<tsource>(IEnumerable<tsource> source, Func<tsource, int,="" bool=""> predicate) {
            int index = -1;
            bool yielding = false;
            foreach (TSource element in source) {
                checked { index++; }
                if (!yielding && !predicate(element, index)) yielding = true;
                if (yielding) yield return element;
            }
        }
 
        public static IEnumerable<tresult> Join<touter, tinner,="" tkey,="" tresult="">(this IEnumerable<touter> outer, IEnumerable<tinner> inner, Func<touter, tkey=""> outerKeySelector, Func<tinner, tkey=""> innerKeySelector, Func<touter, tinner,="" tresult=""> resultSelector) {
            if (outer == null) throw Error.ArgumentNull("outer");
            if (inner == null) throw Error.ArgumentNull("inner");
            if (outerKeySelector == null) throw Error.ArgumentNull("outerKeySelector");
            if (innerKeySelector == null) throw Error.ArgumentNull("innerKeySelector");
            if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
            return JoinIterator<touter, tinner,="" tkey,="" tresult="">(outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
        }
 
        public static IEnumerable<tresult> Join<touter, tinner,="" tkey,="" tresult="">(this IEnumerable<touter> outer, IEnumerable<tinner> inner, Func<touter, tkey=""> outerKeySelector, Func<tinner, tkey=""> innerKeySelector, Func<touter, tinner,="" tresult=""> resultSelector, IEqualityComparer<tkey> comparer) {
            if (outer == null) throw Error.ArgumentNull("outer");
            if (inner == null) throw Error.ArgumentNull("inner");
            if (outerKeySelector == null) throw Error.ArgumentNull("outerKeySelector");
            if (innerKeySelector == null) throw Error.ArgumentNull("innerKeySelector");
            if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
            return JoinIterator<touter, tinner,="" tkey,="" tresult="">(outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
        }
 
        static IEnumerable<tresult> JoinIterator<touter, tinner,="" tkey,="" tresult="">(IEnumerable<touter> outer, IEnumerable<tinner> inner, Func<touter, tkey=""> outerKeySelector, Func<tinner, tkey=""> innerKeySelector, Func<touter, tinner,="" tresult=""> resultSelector, IEqualityComparer<tkey> comparer) {
            Lookup<tkey, tinner=""> lookup = Lookup<tkey, tinner="">.CreateForJoin(inner, innerKeySelector, comparer);
            foreach (TOuter item in outer) {
                Lookup<tkey, tinner="">.Grouping g = lookup.GetGrouping(outerKeySelector(item), false);
                if (g != null) {
                    for (int i = 0; i < g.count; i++) {
                        yield return resultSelector(item, g.elements[i]);
                    }
                }
            }
        }
  
        public static IEnumerable<tresult> GroupJoin<touter, tinner,="" tkey,="" tresult="">(this IEnumerable<touter> outer, IEnumerable<tinner> inner, Func<touter, tkey=""> outerKeySelector, Func<tinner, tkey=""> innerKeySelector, Func<touter, ienumerable<tinner="">, TResult> resultSelector) {
            if (outer == null) throw Error.ArgumentNull("outer");
            if (inner == null) throw Error.ArgumentNull("inner");
            if (outerKeySelector == null) throw Error.ArgumentNull("outerKeySelector");
            if (innerKeySelector == null) throw Error.ArgumentNull("innerKeySelector");
            if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
            return GroupJoinIterator<touter, tinner,="" tkey,="" tresult="">(outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
        }
  
        public static IEnumerable<tresult> GroupJoin<touter, tinner,="" tkey,="" tresult="">(this IEnumerable<touter> outer, IEnumerable<tinner> inner, Func<touter, tkey=""> outerKeySelector, Func<tinner, tkey=""> innerKeySelector, Func<touter, ienumerable<tinner="">, TResult> resultSelector, IEqualityComparer<tkey> comparer) {
            if (outer == null) throw Error.ArgumentNull("outer");
            if (inner == null) throw Error.ArgumentNull("inner");
            if (outerKeySelector == null) throw Error.ArgumentNull("outerKeySelector");
            if (innerKeySelector == null) throw Error.ArgumentNull("innerKeySelector");
            if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
            return GroupJoinIterator<touter, tinner,="" tkey,="" tresult="">(outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
        }
  
        static IEnumerable<tresult> GroupJoinIterator<touter, tinner,="" tkey,="" tresult="">(IEnumerable<touter> outer, IEnumerable<tinner> inner, Func<touter, tkey=""> outerKeySelector, Func<tinner, tkey=""> innerKeySelector, Func<touter, ienumerable<tinner="">, TResult> resultSelector, IEqualityComparer<tkey> comparer) {
            Lookup<tkey, tinner=""> lookup = Lookup<tkey, tinner="">.CreateForJoin(inner, innerKeySelector, comparer);
            foreach (TOuter item in outer) {
                yield return resultSelector(item, lookup[outerKeySelector(item)]);
            }
        }
  
        public static IOrderedEnumerable<tsource> OrderBy<tsource, tkey="">(this IEnumerable<tsource> source, Func<tsource, tkey=""> keySelector) {
            return new OrderedEnumerable<tsource, tkey="">(source, keySelector, null, false);
        }
 
        public static IOrderedEnumerable<tsource> OrderBy<tsource, tkey="">(this IEnumerable<tsource> source, Func<tsource, tkey=""> keySelector, IComparer<tkey> comparer) {
            return new OrderedEnumerable<tsource, tkey="">(source, keySelector, comparer, false);
        }
 
        public static IOrderedEnumerable<tsource> OrderByDescending<tsource, tkey="">(this IEnumerable<tsource> source, Func<tsource, tkey=""> keySelector) {
            return new OrderedEnumerable<tsource, tkey="">(source, keySelector, null, true);
        }
  
        public static IOrderedEnumerable<tsource> OrderByDescending<tsource, tkey="">(this IEnumerable<tsource> source, Func<tsource, tkey=""> keySelector, IComparer<tkey> comparer) {
            return new OrderedEnumerable<tsource, tkey="">(source, keySelector, comparer, true);
        }
 
        public static IOrderedEnumerable<tsource> ThenBy<tsource, tkey="">(this IOrderedEnumerable<tsource> source, Func<tsource, tkey=""> keySelector) {
            if (source == null) throw Error.ArgumentNull("source");
            return source.CreateOrderedEnumerable<tkey>(keySelector, null, false);
        }
  
        public static IOrderedEnumerable<tsource> ThenBy<tsource, tkey="">(this IOrderedEnumerable<tsource> source, Func<tsource, tkey=""> keySelector, IComparer<tkey> comparer) {
            if (source == null) throw Error.ArgumentNull("source");
            return source.CreateOrderedEnumerable<tkey>(keySelector, comparer, false);
        }
 
        public static IOrderedEnumerable<tsource> ThenByDescending<tsource, tkey="">(this IOrderedEnumerable<tsource> source, Func<tsource, tkey=""> keySelector) {
            if (source == null) throw Error.ArgumentNull("source");
            return source.CreateOrderedEnumerable<tkey>(keySelector, null, true);
        }
 
        public static IOrderedEnumerable<tsource> ThenByDescending<tsource, tkey="">(this IOrderedEnumerable<tsource> source, Func<tsource, tkey=""> keySelector, IComparer<tkey> comparer) {
            if (source == null) throw Error.ArgumentNull("source");
            return source.CreateOrderedEnumerable<tkey>(keySelector, comparer, true);
        }
  
        public static IEnumerable<igrouping<tkey, tsource="">> GroupBy<tsource, tkey="">(this IEnumerable<tsource> source, Func<tsource, tkey=""> keySelector) {
            return new GroupedEnumerable<tsource, tkey,="" tsource="">(source, keySelector, IdentityFunction<tsource>.Instance, null);
        }
 
        public static IEnumerable<igrouping<tkey, tsource="">> GroupBy<tsource, tkey="">(this IEnumerable<tsource> source, Func<tsource, tkey=""> keySelector, IEqualityComparer<tkey> comparer) {
            return new GroupedEnumerable<tsource, tkey,="" tsource="">(source, keySelector, IdentityFunction<tsource>.Instance, comparer);
        }
 
        public static IEnumerable<igrouping<tkey, telement="">> GroupBy<tsource, tkey,="" telement="">(this IEnumerable<tsource> source, Func<tsource, tkey=""> keySelector, Func<tsource, telement=""> elementSelector) {
            return new GroupedEnumerable<tsource, tkey,="" telement="">(source, keySelector, elementSelector, null);
        }
  
        public static IEnumerable<igrouping<tkey, telement="">> GroupBy<tsource, tkey,="" telement="">(this IEnumerable<tsource> source, Func<tsource, tkey=""> keySelector, Func<tsource, telement=""> elementSelector, IEqualityComparer<tkey> comparer) {
            return new GroupedEnumerable<tsource, tkey,="" telement="">(source, keySelector, elementSelector, comparer);
        }
 
       public static IEnumerable<tresult> GroupBy<tsource, tkey,="" tresult="">(this IEnumerable<tsource> source, Func<tsource, tkey=""> keySelector, Func<tkey, ienumerable<tsource="">, TResult> resultSelector){
           return  new GroupedEnumerable<tsource, tkey,="" tsource,="" tresult="">(source, keySelector, IdentityFunction<tsource>.Instance, resultSelector, null);
        }
  
        public static IEnumerable<tresult> GroupBy<tsource, tkey,="" telement,="" tresult="">(this IEnumerable<tsource> source, Func<tsource, tkey=""> keySelector, Func<tsource, telement=""> elementSelector, Func<tkey, ienumerable<telement="">, TResult> resultSelector){
           return new GroupedEnumerable<tsource, tkey,="" telement,="" tresult="">(source, keySelector, elementSelector, resultSelector, null);
        }
 
        public static IEnumerable<tresult> GroupBy<tsource, tkey,="" tresult="">(this IEnumerable<tsource> source, Func<tsource, tkey=""> keySelector, Func<tkey, ienumerable<tsource="">, TResult> resultSelector, IEqualityComparer<tkey> comparer){
            return  new GroupedEnumerable<tsource, tkey,="" tsource,="" tresult="">(source, keySelector, IdentityFunction<tsource>.Instance, resultSelector, comparer);
        }
 
        public static IEnumerable<tresult> GroupBy<tsource, tkey,="" telement,="" tresult="">(this IEnumerable<tsource> source, Func<tsource, tkey=""> keySelector, Func<tsource, telement=""> elementSelector, Func<tkey, ienumerable<telement="">, TResult> resultSelector, IEqualityComparer<tkey> comparer){
            return  new GroupedEnumerable<tsource, tkey,="" telement,="" tresult="">(source, keySelector, elementSelector, resultSelector, comparer);
        }
  
        public static IEnumerable<tsource> Concat<tsource>(this IEnumerable<tsource> first, IEnumerable<tsource> second) {
            if (first == null) throw Error.ArgumentNull("first");
            if (second == null) throw Error.ArgumentNull("second");
            return ConcatIterator<tsource>(first, second);
        }
  
        static IEnumerable<tsource> ConcatIterator<tsource>(IEnumerable<tsource> first, IEnumerable<tsource> second) {
            foreach (TSource element in first) yield return element;
            foreach (TSource element in second) yield return element;
        }
 
        public static IEnumerable<tresult> Zip<tfirst, tsecond,="" tresult="">(this IEnumerable<tfirst> first, IEnumerable<tsecond> second, Func<tfirst, tsecond,="" tresult=""> resultSelector) {
            if (first == null) throw Error.ArgumentNull("first");
            if (second == null) throw Error.ArgumentNull("second");
            if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
            return ZipIterator(first, second, resultSelector);
        }
  
        static IEnumerable<tresult> ZipIterator<tfirst, tsecond,="" tresult="">(IEnumerable<tfirst> first, IEnumerable<tsecond> second, Func<tfirst, tsecond,="" tresult=""> resultSelector) {
            using (IEnumerator<tfirst> e1 = first.GetEnumerator())
                using (IEnumerator<tsecond> e2 = second.GetEnumerator())
                    while (e1.MoveNext() && e2.MoveNext())
                        yield return resultSelector(e1.Current, e2.Current);
        }
  
 
        public static IEnumerable<tsource> Distinct<tsource>(this IEnumerable<tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            return DistinctIterator<tsource>(source, null);
        }
  
        public static IEnumerable<tsource> Distinct<tsource>(this IEnumerable<tsource> source, IEqualityComparer<tsource> comparer) {
            if (source == null) throw Error.ArgumentNull("source");
            return DistinctIterator<tsource>(source, comparer);
        }
  
        static IEnumerable<tsource> DistinctIterator<tsource>(IEnumerable<tsource> source, IEqualityComparer<tsource> comparer) {
            Set<tsource> set = new Set<tsource>(comparer);
            foreach (TSource element in source)
                if (set.Add(element)) yield return element;
        }
  
        public static IEnumerable<tsource> Union<tsource>(this IEnumerable<tsource> first, IEnumerable<tsource> second) {
            if (first == null) throw Error.ArgumentNull("first");
            if (second == null) throw Error.ArgumentNull("second");
            return UnionIterator<tsource>(first, second, null);
        }
 
        public static IEnumerable<tsource> Union<tsource>(this IEnumerable<tsource> first, IEnumerable<tsource> second, IEqualityComparer<tsource> comparer)
        {
            if (first == null) throw Error.ArgumentNull("first");
            if (second == null) throw Error.ArgumentNull("second");
            return UnionIterator<tsource>(first, second, comparer);
        }
 
        static IEnumerable<tsource> UnionIterator<tsource>(IEnumerable<tsource> first, IEnumerable<tsource> second, IEqualityComparer<tsource> comparer)
        {
            Set<tsource> set = new Set<tsource>(comparer);
            foreach (TSource element in first)
                if (set.Add(element)) yield return element;
            foreach (TSource element in second)
                if (set.Add(element)) yield return element;
        }
 
        public static IEnumerable<tsource> Intersect<tsource>(this IEnumerable<tsource> first, IEnumerable<tsource> second) {
            if (first == null) throw Error.ArgumentNull("first");
            if (second == null) throw Error.ArgumentNull("second");
            return IntersectIterator<tsource>(first, second, null);
        }
  
        public static IEnumerable<tsource> Intersect<tsource>(this IEnumerable<tsource> first, IEnumerable<tsource> second, IEqualityComparer<tsource> comparer)
        {
            if (first == null) throw Error.ArgumentNull("first");
            if (second == null) throw Error.ArgumentNull("second");
            return IntersectIterator<tsource>(first, second, comparer);
        }
 
        static IEnumerable<tsource> IntersectIterator<tsource>(IEnumerable<tsource> first, IEnumerable<tsource> second, IEqualityComparer<tsource> comparer)
        {
            Set<tsource> set = new Set<tsource>(comparer);
            foreach (TSource element in second) set.Add(element);
            foreach (TSource element in first)
                if (set.Remove(element)) yield return element;
        }
  
        public static IEnumerable<tsource> Except<tsource>(this IEnumerable<tsource> first, IEnumerable<tsource> second)
        {
            if (first == null) throw Error.ArgumentNull("first");
            if (second == null) throw Error.ArgumentNull("second");
            return ExceptIterator<tsource>(first, second, null);
        }
 
        public static IEnumerable<tsource> Except<tsource>(this IEnumerable<tsource> first, IEnumerable<tsource> second, IEqualityComparer<tsource> comparer)
        {
            if (first == null) throw Error.ArgumentNull("first");
            if (second == null) throw Error.ArgumentNull("second");
            return ExceptIterator<tsource>(first, second, comparer);
        }
  
        static IEnumerable<tsource> ExceptIterator<tsource>(IEnumerable<tsource> first, IEnumerable<tsource> second, IEqualityComparer<tsource> comparer) {
            Set</tsource><tsource> set = new Set</tsource><tsource>(comparer);
            foreach (TSource element in second) set.Add(element);
            foreach (TSource element in first)
                if (set.Add(element)) yield return element;
        }
  
        public static IEnumerable</tsource><tsource> Reverse</tsource><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            return ReverseIterator</tsource><tsource>(source);
        }
 
        static IEnumerable</tsource><tsource> ReverseIterator</tsource><tsource>(IEnumerable</tsource><tsource> source) {
            Buffer</tsource><tsource> buffer = new Buffer</tsource><tsource>(source);
            for (int i = buffer.count - 1; i >= 0; i--) yield return buffer.items[i];
        }
 
        public static bool SequenceEqual</tsource><tsource>(this IEnumerable</tsource><tsource> first, IEnumerable</tsource><tsource> second) {
            return SequenceEqual</tsource><tsource>(first, second, null);
        }
 
        public static bool SequenceEqual</tsource><tsource>(this IEnumerable</tsource><tsource> first, IEnumerable</tsource><tsource> second, IEqualityComparer</tsource><tsource> comparer)
        {
            if (comparer == null) comparer = EqualityComparer</tsource><tsource>.Default;
            if (first == null) throw Error.ArgumentNull("first");
            if (second == null) throw Error.ArgumentNull("second");
            using (IEnumerator</tsource><tsource> e1 = first.GetEnumerator())
            using (IEnumerator</tsource><tsource> e2 = second.GetEnumerator())
            {
                while (e1.MoveNext())
                {
                    if (!(e2.MoveNext() && comparer.Equals(e1.Current, e2.Current))) return false;
                }
                if (e2.MoveNext()) return false;
            }
            return true;
        }
 
        public static IEnumerable</tsource><tsource> AsEnumerable</tsource><tsource>(this IEnumerable</tsource><tsource> source)
        {
            return source;
        }
  
        public static TSource[] ToArray</tsource><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            return new Buffer</tsource><tsource>(source).ToArray();
        }
 
        public static List</tsource><tsource> ToList</tsource><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            return new List</tsource><tsource>(source);
        }
 
        public static Dictionary</tsource><tkey, tsource=""> ToDictionary</tkey,><tsource, tkey="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector) {
            return ToDictionary</tsource,><tsource, tkey,="" tsource="">(source, keySelector, IdentityFunction</tsource,><tsource>.Instance, null);
        }
 
        public static Dictionary</tsource><tkey, tsource=""> ToDictionary</tkey,><tsource, tkey="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, IEqualityComparer</tsource,><tkey> comparer) {
            return ToDictionary</tkey><tsource, tkey,="" tsource="">(source, keySelector, IdentityFunction</tsource,><tsource>.Instance, comparer);
        }
  
        public static Dictionary</tsource><tkey, telement=""> ToDictionary</tkey,><tsource, tkey,="" telement="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, Func</tsource,><tsource, telement=""> elementSelector) {
            return ToDictionary</tsource,><tsource, tkey,="" telement="">(source, keySelector, elementSelector, null);
        }
 
        public static Dictionary</tsource,><tkey, telement=""> ToDictionary</tkey,><tsource, tkey,="" telement="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, Func</tsource,><tsource, telement=""> elementSelector, IEqualityComparer</tsource,><tkey> comparer) {
            if (source == null) throw Error.ArgumentNull("source");
            if (keySelector == null) throw Error.ArgumentNull("keySelector");
            if (elementSelector == null) throw Error.ArgumentNull("elementSelector");
            Dictionary</tkey><tkey, telement=""> d = new Dictionary</tkey,><tkey, telement="">(comparer);
            foreach (TSource element in source) d.Add(keySelector(element), elementSelector(element));
            return d;
        }
 
        public static ILookup</tkey,><tkey, tsource=""> ToLookup</tkey,><tsource, tkey="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector) {
            return Lookup</tsource,><tkey, tsource="">.Create(source, keySelector, IdentityFunction</tkey,><tsource>.Instance, null);
        }
  
        public static ILookup</tsource><tkey, tsource=""> ToLookup</tkey,><tsource, tkey="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, IEqualityComparer</tsource,><tkey> comparer) {
            return Lookup</tkey><tkey, tsource="">.Create(source, keySelector, IdentityFunction</tkey,><tsource>.Instance, comparer);
        }
 
        public static ILookup</tsource><tkey, telement=""> ToLookup</tkey,><tsource, tkey,="" telement="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, Func</tsource,><tsource, telement=""> elementSelector) {
            return Lookup</tsource,><tkey, telement="">.Create(source, keySelector, elementSelector, null);
        }
 
        public static ILookup</tkey,><tkey, telement=""> ToLookup</tkey,><tsource, tkey,="" telement="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, Func</tsource,><tsource, telement=""> elementSelector, IEqualityComparer</tsource,><tkey> comparer) {
            return Lookup</tkey><tkey, telement="">.Create(source, keySelector, elementSelector, comparer);
        }
  
        public static IEnumerable</tkey,><tsource> DefaultIfEmpty</tsource><tsource>(this IEnumerable</tsource><tsource> source) {
            return DefaultIfEmpty(source, default(TSource));
        }
  
        public static IEnumerable</tsource><tsource> DefaultIfEmpty</tsource><tsource>(this IEnumerable</tsource><tsource> source, TSource defaultValue) {
            if (source == null) throw Error.ArgumentNull("source");
            return DefaultIfEmptyIterator</tsource><tsource>(source, defaultValue);
        }
  
        static IEnumerable</tsource><tsource> DefaultIfEmptyIterator</tsource><tsource>(IEnumerable</tsource><tsource> source, TSource defaultValue) {
            using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                if (e.MoveNext()) {
                    do {
                        yield return e.Current;
                    } while (e.MoveNext());
                }
                else {
                    yield return defaultValue;
                }
            }
        }
  
        public static IEnumerable</tsource><tresult> OfType</tresult><tresult>(this IEnumerable source) {
            if (source == null) throw Error.ArgumentNull("source");
            return OfTypeIterator</tresult><tresult>(source);
        }
  
        static IEnumerable</tresult><tresult> OfTypeIterator</tresult><tresult>(IEnumerable source) {
            foreach (object obj in source) {
                if (obj is TResult) yield return (TResult)obj;
            }
        }
  
        public static IEnumerable</tresult><tresult> Cast</tresult><tresult>(this IEnumerable source) {
            IEnumerable</tresult><tresult> typedSource = source as IEnumerable</tresult><tresult>;
            if (typedSource != null) return typedSource;
            if (source == null) throw Error.ArgumentNull("source");
            return CastIterator</tresult><tresult>(source);
        }
  
        static IEnumerable</tresult><tresult> CastIterator</tresult><tresult>(IEnumerable source) {
            foreach (object obj in source) yield return (TResult)obj;
        }
 
        public static TSource First</tresult><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            IList</tsource><tsource> list = source as IList</tsource><tsource>;
            if (list != null) {
                if (list.Count > 0) return list[0];
            }
            else {
                using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                    if (e.MoveNext()) return e.Current;
                }
            }
            throw Error.NoElements();
        }
  
        public static TSource First</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            foreach (TSource element in source) {
                if (predicate(element)) return element;
            }
            throw Error.NoMatch();
        }
  
        public static TSource FirstOrDefault</tsource,><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            IList</tsource><tsource> list = source as IList</tsource><tsource>;
            if (list != null) {
                if (list.Count > 0) return list[0];
            }
            else {
                using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                    if (e.MoveNext()) return e.Current;
                }
            }
            return default(TSource);
        }
  
        public static TSource FirstOrDefault</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            foreach (TSource element in source) {
                if (predicate(element)) return element;
            }
            return default(TSource);
        }
  
        public static TSource Last</tsource,><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            IList</tsource><tsource> list = source as IList</tsource><tsource>;
            if (list != null) {
                int count = list.Count;
                if (count > 0) return list[count - 1];
            }
            else {
                using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                    if (e.MoveNext()) {
                        TSource result;
                        do {
                            result = e.Current;
                        } while (e.MoveNext());
                        return result;
                    }
                }
            }
            throw Error.NoElements();
        }
 
        public static TSource Last</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            TSource result = default(TSource);
            bool found = false;
            foreach (TSource element in source) {
                if (predicate(element)) {
                    result = element;
                    found = true;
                }
            }
            if (found) return result;
            throw Error.NoMatch();
        }
  
        public static TSource LastOrDefault</tsource,><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            IList</tsource><tsource> list = source as IList</tsource><tsource>;
            if (list != null) {
                int count = list.Count;
                if (count > 0) return list[count - 1];
            }
            else {
                using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                    if (e.MoveNext()) {
                        TSource result;
                        do {
                            result = e.Current;
                        } while (e.MoveNext());
                        return result;
                    }
                }
            }
            return default(TSource);
        }
 
        public static TSource LastOrDefault</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            TSource result = default(TSource);
            foreach (TSource element in source) {
                if (predicate(element)) {
                    result = element;
                }
            }
            return result;
        }
  
        public static TSource Single</tsource,><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            IList</tsource><tsource> list = source as IList</tsource><tsource>;
            if (list != null) {
                switch (list.Count) {
                    case 0: throw Error.NoElements();
                    case 1: return list[0];
                }
            }
            else {
                using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                    if (!e.MoveNext()) throw Error.NoElements();
                    TSource result = e.Current;
                    if (!e.MoveNext()) return result;
                }
            }
            throw Error.MoreThanOneElement();
        }
  
        public static TSource Single</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            TSource result = default(TSource);
            long count = 0;
            foreach (TSource element in source) {
                if (predicate(element)) {
                    result = element;
                    checked { count++; }
                }
            }
            switch (count) {
                case 0: throw Error.NoMatch();
                case 1: return result;
            }
            throw Error.MoreThanOneMatch();
        }
  
        public static TSource SingleOrDefault</tsource,><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            IList</tsource><tsource> list = source as IList</tsource><tsource>;
            if (list != null) {
                switch (list.Count) {
                    case 0: return default(TSource);
                    case 1: return list[0];
                }
            }
            else {
                using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                    if (!e.MoveNext()) return default(TSource);
                    TSource result = e.Current;
                    if (!e.MoveNext()) return result;
                }
            }
            throw Error.MoreThanOneElement();
        }
 
        public static TSource SingleOrDefault</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            TSource result = default(TSource);
            long count = 0;
            foreach (TSource element in source) {
                if (predicate(element)) {
                    result = element;
                    checked { count++; }
                }
            }
            switch (count) {
                case 0: return default(TSource);
                case 1: return result;
            }
            throw Error.MoreThanOneMatch();
        }
 
        public static TSource ElementAt</tsource,><tsource>(this IEnumerable</tsource><tsource> source, int index) {
            if (source == null) throw Error.ArgumentNull("source");
            IList</tsource><tsource> list = source as IList</tsource><tsource>;
            if (list != null) return list[index];
            if (index < 0) throw Error.ArgumentOutOfRange("index");
            using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                while (true) {
                    if (!e.MoveNext()) throw Error.ArgumentOutOfRange("index");
                    if (index == 0) return e.Current;
                    index--;
                }
            }
        }
  
        public static TSource ElementAtOrDefault</tsource><tsource>(this IEnumerable</tsource><tsource> source, int index) {
            if (source == null) throw Error.ArgumentNull("source");
            if (index >= 0) {
                IList</tsource><tsource> list = source as IList</tsource><tsource>;
                if (list != null) {
                    if (index < list.Count) return list[index];
                }
                else {
                    using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                        while (true) {
                            if (!e.MoveNext()) break;
                            if (index == 0) return e.Current;
                            index--;
                        }
                    }
                }
            }
            return default(TSource);
        }
  
        public static IEnumerable</tsource><int> Range(int start, int count) {
            long max = ((long)start) + count - 1;
            if (count < 0 || max > Int32.MaxValue) throw Error.ArgumentOutOfRange("count");
            return RangeIterator(start, count);
        }
 
        static IEnumerable</int><int> RangeIterator(int start, int count) {
            for (int i = 0; i < count; i++) yield return start + i;
        }
  
        public static IEnumerable</int><tresult> Repeat</tresult><tresult>(TResult element, int count) {
            if (count < 0) throw Error.ArgumentOutOfRange("count");
            return RepeatIterator</tresult><tresult>(element, count);
        }
 
        static IEnumerable</tresult><tresult> RepeatIterator</tresult><tresult>(TResult element, int count) {
            for (int i = 0; i < count; i++) yield return element;
        }
  
        public static IEnumerable</tresult><tresult> Empty</tresult><tresult>() {
            return EmptyEnumerable</tresult><tresult>.Instance;
        }
 
        public static bool Any</tresult><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                if (e.MoveNext()) return true;
            }
            return false;
        }
 
        public static bool Any</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            foreach (TSource element in source) {
                if (predicate(element)) return true;
            }
            return false;
        }
 
        public static bool All</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            foreach (TSource element in source) {
                if (!predicate(element)) return false;
            }
            return true;
        }
 
        public static int Count</tsource,><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            ICollection</tsource><tsource> collectionoft = source as ICollection</tsource><tsource>;
            if (collectionoft != null) return collectionoft.Count;
            ICollection collection = source as ICollection;
            if (collection != null) return collection.Count;
            int count = 0;
            using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                checked {
                    while (e.MoveNext()) count++;
                }
            }
            return count;
        }
  
        public static int Count</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            int count = 0;
            foreach (TSource element in source) {
                checked {
                    if (predicate(element)) count++;
                }
            }
            return count;
        }
 
        public static long LongCount</tsource,><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            long count = 0;
            using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                checked {
                    while (e.MoveNext()) count++;
                }
            }
            return count;
        }
 
        public static long LongCount</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            long count = 0;
            foreach (TSource element in source) {
                checked {
                    if (predicate(element)) count++;
                }
            }
            return count;
        }
  
        public static bool Contains</tsource,><tsource>(this IEnumerable</tsource><tsource> source, TSource value) {
            ICollection</tsource><tsource> collection = source as ICollection</tsource><tsource>;
            if (collection != null) return collection.Contains(value);
            return Contains</tsource><tsource>(source, value, null);
        }
 
        public static bool Contains</tsource><tsource>(this IEnumerable</tsource><tsource> source, TSource value, IEqualityComparer</tsource><tsource> comparer)
        {
            if (comparer == null) comparer = EqualityComparer</tsource><tsource>.Default;
            if (source == null) throw Error.ArgumentNull("source");
            foreach (TSource element in source)
                if (comparer.Equals(element, value)) return true;
            return false;
        }
 
        public static TSource Aggregate</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, tsource,="" tsource=""> func)
        {
            if (source == null) throw Error.ArgumentNull("source");
            if (func == null) throw Error.ArgumentNull("func");
            using (IEnumerator</tsource,><tsource> e = source.GetEnumerator()) {
                if (!e.MoveNext()) throw Error.NoElements();
                TSource result = e.Current;
                while (e.MoveNext()) result = func(result, e.Current);
                return result;
            }
        }
  
        public static TAccumulate Aggregate</tsource><tsource, taccumulate="">(this IEnumerable</tsource,><tsource> source, TAccumulate seed, Func</tsource><taccumulate, tsource,="" taccumulate=""> func) {
            if (source == null) throw Error.ArgumentNull("source");
            if (func == null) throw Error.ArgumentNull("func");
            TAccumulate result = seed;
            foreach (TSource element in source) result = func(result, element);
            return result;
        }
 
        public static TResult Aggregate</taccumulate,><tsource, taccumulate,="" tresult="">(this IEnumerable</tsource,><tsource> source, TAccumulate seed, Func</tsource><taccumulate, tsource,="" taccumulate=""> func, Func</taccumulate,><taccumulate, tresult=""> resultSelector) {
            if (source == null) throw Error.ArgumentNull("source");
            if (func == null) throw Error.ArgumentNull("func");
            if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
            TAccumulate result = seed;
            foreach (TSource element in source) result = func(result, element);
            return resultSelector(result);
        }
 
        public static int Sum(this IEnumerable</taccumulate,><int> source) {
            if (source == null) throw Error.ArgumentNull("source");
            int sum = 0;
            checked {
                foreach (int v in source) sum += v;
            }
            return sum;
        }
 
        public static int? Sum(this IEnumerable</int><int?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            int sum = 0;
            checked {
                foreach (int? v in source) {
                    if (v != null) sum += v.GetValueOrDefault();
                }
            }
            return sum;
        }
  
        public static long Sum(this IEnumerable</int?><long> source) {
            if (source == null) throw Error.ArgumentNull("source");
            long sum = 0;
            checked {
                foreach (long v in source) sum += v;
            }
            return sum;
        }
  
        public static long? Sum(this IEnumerable</long><long?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            long sum = 0;
            checked {
                foreach (long? v in source) {
                    if (v != null) sum += v.GetValueOrDefault();
                }
            }
            return sum;
        }
  
        public static float Sum(this IEnumerable</long?><float> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double sum = 0;
            foreach (float v in source) sum += v;
            return (float)sum;
        }
  
        public static float? Sum(this IEnumerable</float><float?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double sum = 0;
            foreach (float? v in source) {
                if (v != null) sum += v.GetValueOrDefault();
            }
            return (float)sum;
        }
  
        public static double Sum(this IEnumerable</float?><double> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double sum = 0;
            foreach (double v in source) sum += v;
            return sum;
        }
 
        public static double? Sum(this IEnumerable</double><double?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double sum = 0;
            foreach (double? v in source) {
                if (v != null) sum += v.GetValueOrDefault();
            }
            return sum;
        }
 
        public static decimal Sum(this IEnumerable</double?><decimal> source) {
            if (source == null) throw Error.ArgumentNull("source");
            decimal sum = 0;
            foreach (decimal v in source) sum += v;
            return sum;
        }
 
        public static decimal? Sum(this IEnumerable</decimal><decimal?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            decimal sum = 0;
            foreach (decimal? v in source) {
                if (v != null) sum += v.GetValueOrDefault();
            }
            return sum;
        }
 
        public static int Sum</decimal?><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, int=""> selector) {
            return Enumerable.Sum(Enumerable.Select(source, selector));
        }
  
        public static int? Sum</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, int?=""> selector) {
            return Enumerable.Sum(Enumerable.Select(source, selector));
        }
 
        public static long Sum</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, long=""> selector) {
            return Enumerable.Sum(Enumerable.Select(source, selector));
        }
  
        public static long? Sum</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, long?=""> selector) {
            return Enumerable.Sum(Enumerable.Select(source, selector));
        }
 
        public static float Sum</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, float=""> selector) {
            return Enumerable.Sum(Enumerable.Select(source, selector));
        }
 
        public static float? Sum</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, float?=""> selector) {
            return Enumerable.Sum(Enumerable.Select(source, selector));
        }
  
        public static double Sum</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, double=""> selector) {
            return Enumerable.Sum(Enumerable.Select(source, selector));
        }
  
        public static double? Sum</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, double?=""> selector) {
            return Enumerable.Sum(Enumerable.Select(source, selector));
        }
 
        public static decimal Sum</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, decimal=""> selector) {
            return Enumerable.Sum(Enumerable.Select(source, selector));
        }
 
        public static decimal? Sum</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, decimal?=""> selector) {
            return Enumerable.Sum(Enumerable.Select(source, selector));
        }
  
        public static int Min(this IEnumerable</tsource,><int> source) {
            if (source == null) throw Error.ArgumentNull("source");
            int value = 0;
            bool hasValue = false;
            foreach (int x in source) {
                if (hasValue) {
                    if (x < value) value = x;
                }
                else {
                    value = x;
                    hasValue = true;
                }
            }
            if (hasValue) return value;
            throw Error.NoElements();
        }
  
        public static int? Min(this IEnumerable</int><int?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            int? value = null;
            foreach (int? x in source) {
                if (value == null || x < value)
                    value = x;
            }
            return value;
        }
  
        public static long Min(this IEnumerable</int?><long> source) {
            if (source == null) throw Error.ArgumentNull("source");
            long value = 0;
            bool hasValue = false;
            foreach (long x in source) {
                if (hasValue) {
                    if (x < value) value = x;
                }
                else {
                    value = x;
                    hasValue = true;
                }
            }
            if (hasValue) return value;
            throw Error.NoElements();
        }
  
        public static long? Min(this IEnumerable</long><long?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            long? value = null;
            foreach (long? x in source) {
                if (value == null || x < value) value = x;
            }
            return value;
        }
  
        public static float Min(this IEnumerable</long?><float> source) {
            if (source == null) throw Error.ArgumentNull("source");
            float value = 0;
            bool hasValue = false;
            foreach (float x in source) {
                if (hasValue) {
                    // Normally NaN < anything is false, as is anything < NaN
                    // However, this leads to some irksome outcomes in Min and Max.
                    // If we use those semantics then Min(NaN, 5.0) is NaN, but
                    // Min(5.0, NaN) is 5.0!  To fix this, we impose a total
                    // ordering where NaN is smaller than every value, including
                    // negative infinity.
                    if (x < value || System.Single.IsNaN(x)) value = x;
                }
                else {
                    value = x;
                    hasValue = true;
                }
            }
            if (hasValue) return value;
            throw Error.NoElements();
        }
 
        public static float? Min(this IEnumerable</float><float?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            float? value = null;
            foreach (float? x in source) {
                if (x == null) continue;
                if (value == null || x < value || System.Single.IsNaN((float)x)) value = x;
            }
            return value;
        }
 
        public static double Min(this IEnumerable</float?><double> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double value = 0;
            bool hasValue = false;
            foreach (double x in source) {
                if (hasValue) {
                    if (x < value || System.Double.IsNaN(x)) value = x;
                }
                else {
                    value = x;
                    hasValue = true;
                }
            }
            if (hasValue) return value;
            throw Error.NoElements();
        }
 
        public static double? Min(this IEnumerable</double><double?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double? value = null;
            foreach (double? x in source) {
                if (x == null) continue;
                if (value == null || x < value || System.Double.IsNaN((double)x)) value = x;
            }
            return value;
        }
 
        public static decimal Min(this IEnumerable</double?><decimal> source) {
            if (source == null) throw Error.ArgumentNull("source");
            decimal value = 0;
            bool hasValue = false;
            foreach (decimal x in source) {
                if (hasValue) {
                    if (x < value) value = x;
                }
                else {
                    value = x;
                    hasValue = true;
                }
            }
            if (hasValue) return value;
            throw Error.NoElements();
        }
 
        public static decimal? Min(this IEnumerable</decimal><decimal?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            decimal? value = null;
            foreach (decimal? x in source) {
                if (value == null || x < value) value = x;
            }
            return value;
        }
 
        public static TSource Min</decimal?><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            Comparer</tsource><tsource> comparer = Comparer</tsource><tsource>.Default;
            TSource value = default(TSource);
            if (value == null) {
                foreach (TSource x in source) {
                    if (x != null && (value == null || comparer.Compare(x, value) < 0))
                        value = x;
                }
                return value;
            }
            else {
                bool hasValue = false;
                foreach (TSource x in source) {
                    if (hasValue) {
                        if (comparer.Compare(x, value) < 0)
                            value = x;
                    }
                    else {
                        value = x;
                        hasValue = true;
                    }
                }
                if (hasValue) return value;
                throw Error.NoElements();
            }
        }
 
        public static int Min</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, int=""> selector) {
            return Enumerable.Min(Enumerable.Select(source, selector));
        }
  
        public static int? Min</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, int?=""> selector) {
            return Enumerable.Min(Enumerable.Select(source, selector));
        }
 
        public static long Min</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, long=""> selector) {
            return Enumerable.Min(Enumerable.Select(source, selector));
        }
  
        public static long? Min</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, long?=""> selector) {
            return Enumerable.Min(Enumerable.Select(source, selector));
        }
 
        public static float Min</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, float=""> selector) {
            return Enumerable.Min(Enumerable.Select(source, selector));
        }
 
        public static float? Min</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, float?=""> selector) {
            return Enumerable.Min(Enumerable.Select(source, selector));
        }
  
        public static double Min</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, double=""> selector) {
            return Enumerable.Min(Enumerable.Select(source, selector));
        }
  
        public static double? Min</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, double?=""> selector) {
            return Enumerable.Min(Enumerable.Select(source, selector));
        }
 
        public static decimal Min</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, decimal=""> selector) {
            return Enumerable.Min(Enumerable.Select(source, selector));
        }
 
        public static decimal? Min</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, decimal?=""> selector) {
            return Enumerable.Min(Enumerable.Select(source, selector));
        }
  
        public static TResult Min</tsource,><tsource, tresult="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tresult=""> selector) {
            return Enumerable.Min(Enumerable.Select(source, selector));
        }
 
        public static int Max(this IEnumerable</tsource,><int> source) {
            if (source == null) throw Error.ArgumentNull("source");
            int value = 0;
            bool hasValue = false;
            foreach (int x in source) {
                if (hasValue) {
                    if (x > value) value = x;
                }
                else {
                    value = x;
                    hasValue = true;
                }
            }
            if (hasValue) return value;
            throw Error.NoElements();
        }
 
        public static int? Max(this IEnumerable</int><int?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            int? value = null;
            foreach (int? x in source) {
                if (value == null || x > value) value = x;
            }
            return value;
        }
 
        public static long Max(this IEnumerable</int?><long> source) {
            if (source == null) throw Error.ArgumentNull("source");
            long value = 0;
            bool hasValue = false;
            foreach (long x in source) {
                if (hasValue) {
                    if (x > value) value = x;
                }
                else {
                    value = x;
                    hasValue = true;
                }
            }
            if (hasValue) return value;
            throw Error.NoElements();
        }
  
        public static long? Max(this IEnumerable</long><long?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            long? value = null;
            foreach (long? x in source) {
                if (value == null || x > value) value = x;
            }
            return value;
        }
  
        public static double Max(this IEnumerable</long?><double> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double value = 0;
            bool hasValue = false;
            foreach (double x in source) {
                if (hasValue) {
                    if (x > value || System.Double.IsNaN(value)) value = x;
                }
                else {
                    value = x;
                    hasValue = true;
                }
            }
            if (hasValue) return value;
            throw Error.NoElements();
        }
 
        public static double? Max(this IEnumerable</double><double?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double? value = null;
            foreach (double? x in source) {
                if (x == null) continue;
                if (value == null || x > value || System.Double.IsNaN((double)value)) value = x;
            }
            return value;
        }
  
        public static float Max(this IEnumerable</double?><float> source) {
            if (source == null) throw Error.ArgumentNull("source");
            float value = 0;
            bool hasValue = false;
            foreach (float x in source) {
                if (hasValue) {
                    if (x > value || System.Double.IsNaN(value)) value = x;
                }
                else {
                    value = x;
                    hasValue = true;
                }
            }
            if (hasValue) return value;
            throw Error.NoElements();
        }
 
        public static float? Max(this IEnumerable</float><float?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            float? value = null;
            foreach (float? x in source) {
                if (x == null) continue;
                if (value == null || x > value || System.Single.IsNaN((float)value)) value = x;
            }
            return value;
        }
  
        public static decimal Max(this IEnumerable</float?><decimal> source) {
            if (source == null) throw Error.ArgumentNull("source");
            decimal value = 0;
            bool hasValue = false;
            foreach (decimal x in source) {
                if (hasValue) {
                    if (x > value) value = x;
                }
                else {
                    value = x;
                    hasValue = true;
                }
            }
            if (hasValue) return value;
            throw Error.NoElements();
        }
 
        public static decimal? Max(this IEnumerable</decimal><decimal?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            decimal? value = null;
            foreach (decimal? x in source) {
                if (value == null || x > value) value = x;
            }
            return value;
        }
 
        public static TSource Max</decimal?><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            Comparer</tsource><tsource> comparer = Comparer</tsource><tsource>.Default;
            TSource value = default(TSource);
            if (value == null) {
                foreach (TSource x in source) {
                    if (x != null && (value == null || comparer.Compare(x, value) > 0))
                        value = x;
                }
                return value;
            }
            else {
                bool hasValue = false;
                foreach (TSource x in source) {
                    if (hasValue) {
                        if (comparer.Compare(x, value) > 0)
                            value = x;
                    }
                    else {
                        value = x;
                        hasValue = true;
                    }
                }
                if (hasValue) return value;
                throw Error.NoElements();
            }
        }
  
        public static int Max</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, int=""> selector) {
            return Enumerable.Max(Enumerable.Select(source, selector));
        }
  
        public static int? Max</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, int?=""> selector) {
            return Enumerable.Max(Enumerable.Select(source, selector));
        }
 
        public static long Max</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, long=""> selector) {
            return Enumerable.Max(Enumerable.Select(source, selector));
        }
 
        public static long? Max</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, long?=""> selector) {
            return Enumerable.Max(Enumerable.Select(source, selector));
        }
  
        public static float Max</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, float=""> selector) {
            return Enumerable.Max(Enumerable.Select(source, selector));
        }
 
        public static float? Max</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, float?=""> selector) {
            return Enumerable.Max(Enumerable.Select(source, selector));
        }
  
        public static double Max</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, double=""> selector) {
            return Enumerable.Max(Enumerable.Select(source, selector));
        }
 
        public static double? Max</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, double?=""> selector) {
            return Enumerable.Max(Enumerable.Select(source, selector));
        }
 
        public static decimal Max</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, decimal=""> selector) {
            return Enumerable.Max(Enumerable.Select(source, selector));
        }
  
        public static decimal? Max</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, decimal?=""> selector) {
            return Enumerable.Max(Enumerable.Select(source, selector));
        }
  
        public static TResult Max</tsource,><tsource, tresult="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tresult=""> selector) {
            return Enumerable.Max(Enumerable.Select(source, selector));
        }
 
        public static double Average(this IEnumerable</tsource,><int> source) {
            if (source == null) throw Error.ArgumentNull("source");
            long sum = 0;
            long count = 0;
            checked {
                foreach (int v in source) {
                    sum += v;
                    count++;
                }
            }
            if (count > 0) return (double)sum / count;
            throw Error.NoElements();
        }
  
        public static double? Average(this IEnumerable</int><int?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            long sum = 0;
            long count = 0;
            checked {
                foreach (int? v in source) {
                    if (v != null) {
                        sum += v.GetValueOrDefault();
                        count++;
                    }
                }
            }
            if (count > 0) return (double)sum / count;
            return null;
        }
 
        public static double Average(this IEnumerable</int?><long> source) {
            if (source == null) throw Error.ArgumentNull("source");
            long sum = 0;
            long count = 0;
            checked {
                foreach (long v in source) {
                    sum += v;
                    count++;
                }
            }
            if (count > 0) return (double)sum / count;
            throw Error.NoElements();
        }
  
        public static double? Average(this IEnumerable</long><long?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            long sum = 0;
            long count = 0;
            checked {
                foreach (long? v in source) {
                    if (v != null) {
                        sum += v.GetValueOrDefault();
                        count++;
                    }
                }
            }
            if (count > 0) return (double)sum / count;
            return null;
        }
 
        public static float Average(this IEnumerable</long?><float> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double sum = 0;
            long count = 0;
            checked {
                foreach (float v in source) {
                    sum += v;
                    count++;
                }
            }
            if (count > 0) return (float)(sum / count);
            throw Error.NoElements();
        }
 
        public static float? Average(this IEnumerable</float><float?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double sum = 0;
            long count = 0;
            checked {
                foreach (float? v in source) {
                    if (v != null) {
                        sum += v.GetValueOrDefault();
                        count++;
                    }
                }
            }
            if (count > 0) return (float)(sum / count);
            return null;
        }
 
        public static double Average(this IEnumerable</float?><double> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double sum = 0;
            long count = 0;
            checked {
                foreach (double v in source) {
                    sum += v;
                    count++;
                }
            }
            if (count > 0) return sum / count;
            throw Error.NoElements();
        }
  
        public static double? Average(this IEnumerable</double><double?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double sum = 0;
            long count = 0;
            checked {
                foreach (double? v in source) {
                    if (v != null) {
                        sum += v.GetValueOrDefault();
                        count++;
                    }
                }
            }
            if (count > 0) return sum / count;
            return null;
        }
 
        public static decimal Average(this IEnumerable</double?><decimal> source) {
            if (source == null) throw Error.ArgumentNull("source");
            decimal sum = 0;
            long count = 0;
            checked {
                foreach (decimal v in source) {
                    sum += v;
                    count++;
                }
            }
            if (count > 0) return sum / count;
            throw Error.NoElements();
        }
  
        public static decimal? Average(this IEnumerable</decimal><decimal?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            decimal sum = 0;
            long count = 0;
            checked {
                foreach (decimal? v in source) {
                    if (v != null) {
                        sum += v.GetValueOrDefault();
                        count++;
                    }
                }
            }
            if (count > 0) return sum / count;
            return null;
        }
 
        public static double Average</decimal?><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, int=""> selector) {
            return Enumerable.Average(Enumerable.Select(source, selector));
        }
  
        public static double? Average</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, int?=""> selector) {
            return Enumerable.Average(Enumerable.Select(source, selector));
        }
  
        public static double Average</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, long=""> selector) {
            return Enumerable.Average(Enumerable.Select(source, selector));
        }
 
        public static double? Average</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, long?=""> selector) {
            return Enumerable.Average(Enumerable.Select(source, selector));
        }
 
        public static float Average</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, float=""> selector) {
            return Enumerable.Average(Enumerable.Select(source, selector));
        }
  
        public static float? Average</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, float?=""> selector) {
            return Enumerable.Average(Enumerable.Select(source, selector));
        }
 
        public static double Average</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, double=""> selector) {
            return Enumerable.Average(Enumerable.Select(source, selector));
        }
  
        public static double? Average</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, double?=""> selector) {
            return Enumerable.Average(Enumerable.Select(source, selector));
        }
 
        public static decimal Average</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, decimal=""> selector) {
            return Enumerable.Average(Enumerable.Select(source, selector));
        }
 
        public static decimal? Average</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, decimal?=""> selector) {
            return Enumerable.Average(Enumerable.Select(source, selector));
        }
    }
 
    internal class EmptyEnumerable</tsource,><telement>
    {
        static TElement[] instance;
 
        public static IEnumerable</telement><telement> Instance {
            get {
                if (instance == null) instance = new TElement[0];
                return instance;
            }
        }
    }
  
    internal class IdentityFunction</telement><telement>
    {
        public static Func</telement><telement, telement=""> Instance {
            get { return x => x; }
        }
    }
 
    public interface IOrderedEnumerable</telement,><telement> : IEnumerable</telement><telement>
    {
        IOrderedEnumerable</telement><telement> CreateOrderedEnumerable</telement><tkey>(Func</tkey><telement, tkey=""> keySelector, IComparer</telement,><tkey> comparer, bool descending);
    }
  
#if SILVERLIGHT
    public interface IGrouping</tkey><tkey, telement=""> : IEnumerable</tkey,><telement>
#else
    public interface IGrouping</telement><out tkey,="" out="" telement=""> : IEnumerable</out><telement>
#endif
    {
        TKey Key { get; }
    }
  
    public interface ILookup</telement><tkey, telement=""> : IEnumerable</tkey,><igrouping<tkey, telement="">>{
        int Count { get; }
        IEnumerable</igrouping<tkey,><telement> this[TKey key] { get; }
        bool Contains(TKey key);
    }
  
    public class Lookup</telement><tkey, telement=""> : IEnumerable</tkey,><igrouping<tkey, telement="">>, ILookup</igrouping<tkey,><tkey, telement="">{
        IEqualityComparer</tkey,><tkey> comparer;
        Grouping[] groupings;
        Grouping lastGrouping;
        int count;
 
        internal static Lookup</tkey><tkey, telement=""> Create</tkey,><tsource>(IEnumerable</tsource><tsource> source, Func</tsource><tsource, tkey=""> keySelector, Func</tsource,><tsource, telement=""> elementSelector, IEqualityComparer</tsource,><tkey> comparer) {
            if (source == null) throw Error.ArgumentNull("source");
            if (keySelector == null) throw Error.ArgumentNull("keySelector");
            if (elementSelector == null) throw Error.ArgumentNull("elementSelector");
            Lookup</tkey><tkey, telement=""> lookup = new Lookup</tkey,><tkey, telement="">(comparer);
            foreach (TSource item in source) {
                lookup.GetGrouping(keySelector(item), true).Add(elementSelector(item));
            }
            return lookup;
        }
 
        internal static Lookup</tkey,><tkey, telement=""> CreateForJoin(IEnumerable</tkey,><telement> source, Func</telement><telement, tkey=""> keySelector, IEqualityComparer</telement,><tkey> comparer) {
            Lookup</tkey><tkey, telement=""> lookup = new Lookup</tkey,><tkey, telement="">(comparer);
            foreach (TElement item in source) {
                TKey key = keySelector(item);
                if (key != null) lookup.GetGrouping(key, true).Add(item);
            }
            return lookup;
        }
 
        Lookup(IEqualityComparer</tkey,><tkey> comparer) {
            if (comparer == null) comparer = EqualityComparer</tkey><tkey>.Default;
            this.comparer = comparer;
            groupings = new Grouping[7];
        }
  
        public int Count {
            get { return count; }
        }
  
        public IEnumerable</tkey><telement> this[TKey key] {
            get {
                Grouping grouping = GetGrouping(key, false);
                if (grouping != null) return grouping;
                return EmptyEnumerable</telement><telement>.Instance;
            }
        }
 
        public bool Contains(TKey key) {
            return GetGrouping(key, false) != null;
        }
  
        public IEnumerator</telement><igrouping<tkey, telement="">> GetEnumerator() {
            Grouping g = lastGrouping;
            if (g != null) {
                do {
                    g = g.next;
                    yield return g;
                } while (g != lastGrouping);
            }
        }
 
        public IEnumerable</igrouping<tkey,><tresult> ApplyResultSelector</tresult><tresult>(Func</tresult><tkey, ienumerable<telement="">, TResult> resultSelector){
            Grouping g = lastGrouping;
            if (g != null) {
                do {
                    g = g.next;
                    if (g.count != g.elements.Length) { Array.Resize</tkey,><telement>(ref g.elements, g.count); }
                    yield return resultSelector(g.key, g.elements);
                }while (g != lastGrouping);
            }
        }
 
        IEnumerator IEnumerable.GetEnumerator() {
            return GetEnumerator();
        }
 
        internal int InternalGetHashCode(TKey key)
        {
            //[....] DevDivBugs 171937. work around comparer implementations that throw when passed null
            return (key == null) ? 0 : comparer.GetHashCode(key) & 0x7FFFFFFF;
        }
 
        internal Grouping GetGrouping(TKey key, bool create) {
            int hashCode = InternalGetHashCode(key);
            for (Grouping g = groupings[hashCode % groupings.Length]; g != null; g = g.hashNext)
                if (g.hashCode == hashCode && comparer.Equals(g.key, key)) return g;
            if (create) {
                if (count == groupings.Length) Resize();
                int index = hashCode % groupings.Length;
                Grouping g = new Grouping();
                g.key = key;
                g.hashCode = hashCode;
                g.elements = new TElement[1];
                g.hashNext = groupings[index];
                groupings[index] = g;
                if (lastGrouping == null) {
                    g.next = g;
                }
                else {
                    g.next = lastGrouping.next;
                    lastGrouping.next = g;
                }
                lastGrouping = g;
                count++;
                return g;
            }
            return null;
        }
 
        void Resize() {
            int newSize = checked(count * 2 + 1);
            Grouping[] newGroupings = new Grouping[newSize];
            Grouping g = lastGrouping;
            do {
                g = g.next;
                int index = g.hashCode % newSize;
                g.hashNext = newGroupings[index];
                newGroupings[index] = g;
            } while (g != lastGrouping);
            groupings = newGroupings;
        }
  
        internal class Grouping : IGrouping</telement><tkey, telement="">, IList</tkey,><telement>
        {
            internal TKey key;
            internal int hashCode;
            internal TElement[] elements;
            internal int count;
            internal Grouping hashNext;
            internal Grouping next;
  
            internal void Add(TElement element) {
                if (elements.Length == count) Array.Resize(ref elements, checked(count * 2));
                elements[count] = element;
                count++;
            }
 
            public IEnumerator</telement><telement> GetEnumerator() {
                for (int i = 0; i < count; i++) yield return elements[i];
            }
  
            IEnumerator IEnumerable.GetEnumerator() {
                return GetEnumerator();
            }
 
            // DDB195907: implement IGrouping<>.Key implicitly
            // so that WPF binding works on this property.
            public TKey Key {
                get { return key; }
            }
 
            int ICollection</telement><telement>.Count {
                get { return count; }
            }
 
            bool ICollection</telement><telement>.IsReadOnly {
                get { return true; }
            }
  
            void ICollection</telement><telement>.Add(TElement item) {
                throw Error.NotSupported();
            }
 
            void ICollection</telement><telement>.Clear() {
                throw Error.NotSupported();
            }
  
            bool ICollection</telement><telement>.Contains(TElement item) {
                return Array.IndexOf(elements, item, 0, count) >= 0;
            }
 
            void ICollection</telement><telement>.CopyTo(TElement[] array, int arrayIndex) {
                Array.Copy(elements, 0, array, arrayIndex, count);
            }
 
            bool ICollection</telement><telement>.Remove(TElement item) {
                throw Error.NotSupported();
            }
  
            int IList</telement><telement>.IndexOf(TElement item) {
                return Array.IndexOf(elements, item, 0, count);
            }
  
            void IList</telement><telement>.Insert(int index, TElement item) {
                throw Error.NotSupported();
            }
 
            void IList</telement><telement>.RemoveAt(int index) {
                throw Error.NotSupported();
            }
 
            TElement IList</telement><telement>.this[int index] {
                get {
                    if (index < 0 || index >= count) throw Error.ArgumentOutOfRange("index");
                    return elements[index];
                }
                set {
                    throw Error.NotSupported();
                }
            }
        }
    }
  
    internal class Set</telement><telement>
    {
        int[] buckets;
        Slot[] slots;
        int count;
        int freeList;
        IEqualityComparer</telement><telement> comparer;
 
        public Set() : this(null) { }
  
        public Set(IEqualityComparer</telement><telement> comparer) {
            if (comparer == null) comparer = EqualityComparer</telement><telement>.Default;
            this.comparer = comparer;
            buckets = new int[7];
            slots = new Slot[7];
            freeList = -1;
        }
  
        // If value is not in set, add it and return true; otherwise return false
        public bool Add(TElement value) {
            return !Find(value, true);
        }
 
        // Check whether value is in set
        public bool Contains(TElement value) {
            return Find(value, false);
        }
  
        // If value is in set, remove it and return true; otherwise return false
        public bool Remove(TElement value) {
            int hashCode = InternalGetHashCode(value);
            int bucket = hashCode % buckets.Length;
            int last = -1;
            for (int i = buckets[bucket] - 1; i >= 0; last = i, i = slots[i].next) {
                if (slots[i].hashCode == hashCode && comparer.Equals(slots[i].value, value)) {
                    if (last < 0) {
                        buckets[bucket] = slots[i].next + 1;
                    }
                    else {
                        slots[last].next = slots[i].next;
                    }
                    slots[i].hashCode = -1;
                    slots[i].value = default(TElement);
                    slots[i].next = freeList;
                    freeList = i;
                    return true;
                }
            }
            return false;
        }
 
        bool Find(TElement value, bool add) {
            int hashCode = InternalGetHashCode(value);
            for (int i = buckets[hashCode % buckets.Length] - 1; i >= 0; i = slots[i].next) {
                if (slots[i].hashCode == hashCode && comparer.Equals(slots[i].value, value)) return true;
            }
            if (add) {
                int index;
                if (freeList >= 0) {
                    index = freeList;
                    freeList = slots[index].next;
                }
                else {
                    if (count == slots.Length) Resize();
                    index = count;
                    count++;
                }
                int bucket = hashCode % buckets.Length;
                slots[index].hashCode = hashCode;
                slots[index].value = value;
                slots[index].next = buckets[bucket] - 1;
                buckets[bucket] = index + 1;
            }
            return false;
        }
 
        void Resize() {
            int newSize = checked(count * 2 + 1);
            int[] newBuckets = new int[newSize];
            Slot[] newSlots = new Slot[newSize];
            Array.Copy(slots, 0, newSlots, 0, count);
            for (int i = 0; i < count; i++) {
                int bucket = newSlots[i].hashCode % newSize;
                newSlots[i].next = newBuckets[bucket] - 1;
                newBuckets[bucket] = i + 1;
            }
            buckets = newBuckets;
            slots = newSlots;
        }
  
        internal int InternalGetHashCode(TElement value)
        {
            //[....] DevDivBugs 171937. work around comparer implementations that throw when passed null
            return (value == null) ? 0 : comparer.GetHashCode(value) & 0x7FFFFFFF;
        }
 
        internal struct Slot
        {
            internal int hashCode;
            internal TElement value;
            internal int next;
        }
    }
 
    internal class GroupedEnumerable</telement><tsource, tkey,="" telement,="" tresult=""> : IEnumerable</tsource,><tresult>{
        IEnumerable</tresult><tsource> source;
        Func</tsource><tsource, tkey=""> keySelector;
        Func</tsource,><tsource, telement=""> elementSelector;
        IEqualityComparer</tsource,><tkey> comparer;
        Func</tkey><tkey, ienumerable<telement="">, TResult> resultSelector;
  
        public GroupedEnumerable(IEnumerable</tkey,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, Func</tsource,><tsource, telement=""> elementSelector, Func</tsource,><tkey, ienumerable<telement="">, TResult> resultSelector, IEqualityComparer</tkey,><tkey> comparer){
            if (source == null) throw Error.ArgumentNull("source");
            if (keySelector == null) throw Error.ArgumentNull("keySelector");
            if (elementSelector == null) throw Error.ArgumentNull("elementSelector");
            if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
            this.source = source;
            this.keySelector = keySelector;
            this.elementSelector = elementSelector;
            this.comparer = comparer;
            this.resultSelector = resultSelector;
        }
 
        public IEnumerator</tkey><tresult> GetEnumerator(){
            Lookup</tresult><tkey, telement=""> lookup = Lookup</tkey,><tkey, telement="">.Create</tkey,><tsource>(source, keySelector, elementSelector, comparer);
            return lookup.ApplyResultSelector(resultSelector).GetEnumerator();
        }
 
        IEnumerator IEnumerable.GetEnumerator(){
            return GetEnumerator();
        }
    }
  
    internal class GroupedEnumerable</tsource><tsource, tkey,="" telement=""> : IEnumerable</tsource,><igrouping<tkey, telement="">>
    {
        IEnumerable</igrouping<tkey,><tsource> source;
        Func</tsource><tsource, tkey=""> keySelector;
        Func</tsource,><tsource, telement=""> elementSelector;
        IEqualityComparer</tsource,><tkey> comparer;
 
        public GroupedEnumerable(IEnumerable</tkey><tsource> source, Func</tsource><tsource, tkey=""> keySelector, Func</tsource,><tsource, telement=""> elementSelector, IEqualityComparer</tsource,><tkey> comparer) {
            if (source == null) throw Error.ArgumentNull("source");
            if (keySelector == null) throw Error.ArgumentNull("keySelector");
            if (elementSelector == null) throw Error.ArgumentNull("elementSelector");
            this.source = source;
            this.keySelector = keySelector;
            this.elementSelector = elementSelector;
            this.comparer = comparer;
        }
 
        public IEnumerator</tkey><igrouping<tkey, telement="">> GetEnumerator() {
            return Lookup</igrouping<tkey,><tkey, telement="">.Create</tkey,><tsource>(source, keySelector, elementSelector, comparer).GetEnumerator();
        }
  
        IEnumerator IEnumerable.GetEnumerator() {
            return GetEnumerator();
        }
    }
 
    internal abstract class OrderedEnumerable</tsource><telement> : IOrderedEnumerable</telement><telement>
    {
        internal IEnumerable</telement><telement> source;
  
        public IEnumerator</telement><telement> GetEnumerator() {
            Buffer</telement><telement> buffer = new Buffer</telement><telement>(source);
            if (buffer.count > 0) {
                EnumerableSorter</telement><telement> sorter = GetEnumerableSorter(null);
                int[] map = sorter.Sort(buffer.items, buffer.count);
                sorter = null;
                for (int i = 0; i < buffer.count; i++) yield return buffer.items[map[i]];
            }
        }
 
        internal abstract EnumerableSorter</telement><telement> GetEnumerableSorter(EnumerableSorter</telement><telement> next);
 
        IEnumerator IEnumerable.GetEnumerator() {
            return GetEnumerator();
        }
 
        IOrderedEnumerable</telement><telement> IOrderedEnumerable</telement><telement>.CreateOrderedEnumerable</telement><tkey>(Func</tkey><telement, tkey=""> keySelector, IComparer</telement,><tkey> comparer, bool descending) {
            OrderedEnumerable</tkey><telement, tkey=""> result = new OrderedEnumerable</telement,><telement, tkey="">(source, keySelector, comparer, descending);
            result.parent = this;
            return result;
        }
    }
 
    internal class OrderedEnumerable</telement,><telement, tkey=""> : OrderedEnumerable</telement,><telement>
    {
        internal OrderedEnumerable</telement><telement> parent;
        internal Func</telement><telement, tkey=""> keySelector;
        internal IComparer</telement,><tkey> comparer;
        internal bool descending;
 
        internal OrderedEnumerable(IEnumerable</tkey><telement> source, Func</telement><telement, tkey=""> keySelector, IComparer</telement,><tkey> comparer, bool descending) {
            if (source == null) throw Error.ArgumentNull("source");
            if (keySelector == null) throw Error.ArgumentNull("keySelector");
            this.source = source;
            this.parent = null;
            this.keySelector = keySelector;
            this.comparer = comparer != null ? comparer : Comparer</tkey><tkey>.Default;
            this.descending = descending;
        }
 
        internal override EnumerableSorter</tkey><telement> GetEnumerableSorter(EnumerableSorter</telement><telement> next) {
            EnumerableSorter</telement><telement> sorter = new EnumerableSorter</telement><telement, tkey="">(keySelector, comparer, descending, next);
            if (parent != null) sorter = parent.GetEnumerableSorter(sorter);
            return sorter;
        }
    }
  
    internal abstract class EnumerableSorter</telement,><telement>
    {
        internal abstract void ComputeKeys(TElement[] elements, int count);
  
        internal abstract int CompareKeys(int index1, int index2);
  
        internal int[] Sort(TElement[] elements, int count) {
            ComputeKeys(elements, count);
            int[] map = new int[count];
            for (int i = 0; i < count; i++) map[i] = i;
            QuickSort(map, 0, count - 1);
            return map;
        }
 
        void QuickSort(int[] map, int left, int right) {
            do {
                int i = left;
                int j = right;
                int x = map[i + ((j - i) >> 1)];
                do {
                    while (i < map.Length && CompareKeys(x, map[i]) > 0) i++;
                    while (j >= 0 && CompareKeys(x, map[j]) < 0) j--;
                    if (i > j) break;
                    if (i < j) {
                        int temp = map[i];
                        map[i] = map[j];
                        map[j] = temp;
                    }
                    i++;
                    j--;
                } while (i <= j);
                if (j - left <= right - i) {
                    if (left < j) QuickSort(map, left, j);
                    left = i;
                }
                else {
                    if (i < right) QuickSort(map, i, right);
                    right = j;
                }
            } while (left < right);
        }
    }
  
    internal class EnumerableSorter</telement><telement, tkey=""> : EnumerableSorter</telement,><telement>
    {
        internal Func</telement><telement, tkey=""> keySelector;
        internal IComparer</telement,><tkey> comparer;
        internal bool descending;
        internal EnumerableSorter</tkey><telement> next;
        internal TKey[] keys;
  
        internal EnumerableSorter(Func</telement><telement, tkey=""> keySelector, IComparer</telement,><tkey> comparer, bool descending, EnumerableSorter</tkey><telement> next) {
            this.keySelector = keySelector;
            this.comparer = comparer;
            this.descending = descending;
            this.next = next;
        }
  
        internal override void ComputeKeys(TElement[] elements, int count) {
            keys = new TKey[count];
            for (int i = 0; i < count; i++) keys[i] = keySelector(elements[i]);
            if (next != null) next.ComputeKeys(elements, count);
        }
 
        internal override int CompareKeys(int index1, int index2) {
            int c = comparer.Compare(keys[index1], keys[index2]);
            if (c == 0) {
                if (next == null) return index1 - index2;
                return next.CompareKeys(index1, index2);
            }
            return descending ? -c : c;
        }
    }
 
    struct Buffer</telement><telement>
    {
        internal TElement[] items;
        internal int count;
  
        internal Buffer(IEnumerable</telement><telement> source) {
            TElement[] items = null;
            int count = 0;
            ICollection</telement><telement> collection = source as ICollection</telement><telement>;
            if (collection != null) {
                count = collection.Count;
                if (count > 0) {
                    items = new TElement[count];
                    collection.CopyTo(items, 0);
                }
            }
            else {
                foreach (TElement item in source) {
                    if (items == null) {
                        items = new TElement[4];
                    }
                    else if (items.Length == count) {
                        TElement[] newItems = new TElement[checked(count * 2)];
                        Array.Copy(items, 0, newItems, 0, count);
                        items = newItems;
                    }
                    items[count] = item;
                    count++;
                }
            }
            this.items = items;
            this.count = count;
        }
  
        internal TElement[] ToArray() {
            if (count == 0) return new TElement[0];
            if (items.Length == count) return items;
            TElement[] result = new TElement[count];
            Array.Copy(items, 0, result, 0, count);
            return result;
        }
    }
  
    ///
    /// 
    internal sealed class SystemCore_EnumerableDebugView</telement><summary>
    /// This class provides the items view for the Enumerable
    /// </summary><typeparam name="T"></typeparam><t>
    {
        public SystemCore_EnumerableDebugView(IEnumerable</t><t> enumerable)
        {
            if (enumerable == null)
            {
                throw new ArgumentNullException("enumerable");
            }
  
            this.enumerable = enumerable;
        }
  
        [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)]
        public T[] Items
        {
            get
            {
                List</t><t> tempList = new List</t><t>();
                IEnumerator</t><t> currentEnumerator = this.enumerable.GetEnumerator();
  
                if (currentEnumerator != null)
                {
                    for(count = 0; currentEnumerator.MoveNext(); count++)
                    {
                        tempList.Add(currentEnumerator.Current);
                    }
                }
                if (count == 0)
                {
                    throw new SystemCore_EnumerableDebugViewEmptyException();
                }
                cachedCollection = new T[this.count];
                tempList.CopyTo(cachedCollection, 0);
                return cachedCollection;
            }
        }
 
        [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
        private IEnumerable</t><t> enumerable;
 
        [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
        private T[] cachedCollection;
 
        [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
        private int count;
    }
  
    internal sealed class SystemCore_EnumerableDebugViewEmptyException : Exception
    {
        public string Empty
        {
            get
            {
                return Strings.EmptyEnumerable;
            }
        }
    }
 
    internal sealed class SystemCore_EnumerableDebugView
    {
        public SystemCore_EnumerableDebugView(IEnumerable enumerable)
        {
            if (enumerable == null)
            {
                throw new ArgumentNullException("enumerable");
            }
 
            this.enumerable = enumerable;
            count = 0;
            cachedCollection = null;
        }
  
        [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)]
        public object[] Items
        {
            get
            {
                List</t><object> tempList = new List</object><object>();
                IEnumerator currentEnumerator = this.enumerable.GetEnumerator();
 
                if (currentEnumerator != null)
                {
                    for (count = 0; currentEnumerator.MoveNext(); count++)
                    {
                        tempList.Add(currentEnumerator.Current);
                    }
                }
                if (count == 0)
                {
                    throw new SystemCore_EnumerableDebugViewEmptyException();
                }
                cachedCollection = new object[this.count];
                tempList.CopyTo(cachedCollection, 0);
                return cachedCollection;
            }
        }
 
        [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
        private IEnumerable enumerable;
 
        [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
        private object[] cachedCollection;
 
        [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
        private int count;
    }
}
 
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
  
// Include Silverlight's managed resources
#if SILVERLIGHT
using System.Core;
#endif //SILVERLIGHT
  
namespace System.Linq
{
    public static class Enumerable
    {
        public static IEnumerable</object><tsource> Where</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            if (source is Iterator</tsource,><tsource>) return ((Iterator</tsource><tsource>)source).Where(predicate);
            if (source is TSource[]) return new WhereArrayIterator</tsource><tsource>((TSource[])source, predicate);
            if (source is List</tsource><tsource>) return new WhereListIterator</tsource><tsource>((List</tsource><tsource>)source, predicate);
            return new WhereEnumerableIterator</tsource><tsource>(source, predicate);
        }
  
        public static IEnumerable</tsource><tsource> Where</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, int,="" bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            return WhereIterator</tsource,><tsource>(source, predicate);
        }
 
        static IEnumerable</tsource><tsource> WhereIterator</tsource><tsource>(IEnumerable</tsource><tsource> source, Func</tsource><tsource, int,="" bool=""> predicate) {
            int index = -1;
            foreach (TSource element in source) {
                checked { index++; }
                if (predicate(element, index)) yield return element;
            }
        }
  
        public static IEnumerable</tsource,><tresult> Select</tresult><tsource, tresult="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tresult=""> selector) {
            if (source == null) throw Error.ArgumentNull("source");
            if (selector == null) throw Error.ArgumentNull("selector");
            if (source is Iterator</tsource,><tsource>) return ((Iterator</tsource><tsource>)source).Select(selector);
            if (source is TSource[]) return new WhereSelectArrayIterator</tsource><tsource, tresult="">((TSource[])source, null, selector);
            if (source is List</tsource,><tsource>) return new WhereSelectListIterator</tsource><tsource, tresult="">((List</tsource,><tsource>)source, null, selector);
            return new WhereSelectEnumerableIterator</tsource><tsource, tresult="">(source, null, selector);
        }
  
        public static IEnumerable</tsource,><tresult> Select</tresult><tsource, tresult="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, int,="" tresult=""> selector) {
            if (source == null) throw Error.ArgumentNull("source");
            if (selector == null) throw Error.ArgumentNull("selector");
            return SelectIterator</tsource,><tsource, tresult="">(source, selector);
        }
  
        static IEnumerable</tsource,><tresult> SelectIterator</tresult><tsource, tresult="">(IEnumerable</tsource,><tsource> source, Func</tsource><tsource, int,="" tresult=""> selector) {
            int index = -1;
            foreach (TSource element in source) {
                checked { index++; }
                yield return selector(element, index);
            }
        }
 
        static Func</tsource,><tsource, bool=""> CombinePredicates</tsource,><tsource>(Func</tsource><tsource, bool=""> predicate1, Func</tsource,><tsource, bool=""> predicate2) {
            return x => predicate1(x) && predicate2(x);
        }
  
        static Func</tsource,><tsource, tresult=""> CombineSelectors</tsource,><tsource, tmiddle,="" tresult="">(Func</tsource,><tsource, tmiddle=""> selector1, Func</tsource,><tmiddle, tresult=""> selector2) {
            return x => selector2(selector1(x));
        }
  
        abstract class Iterator</tmiddle,><tsource> : IEnumerable</tsource><tsource>, IEnumerator</tsource><tsource>
        {
            int threadId;
            internal int state;
            internal TSource current;
 
            public Iterator() {
                threadId = Thread.CurrentThread.ManagedThreadId;
            }
 
            public TSource Current {
                get { return current; }
            }
  
            public abstract Iterator</tsource><tsource> Clone();
 
            public virtual void Dispose() {
                current = default(TSource);
                state = -1;
            }
  
            public IEnumerator</tsource><tsource> GetEnumerator() {
                if (threadId == Thread.CurrentThread.ManagedThreadId && state == 0) {
                    state = 1;
                    return this;
                }
                Iterator</tsource><tsource> duplicate = Clone();
                duplicate.state = 1;
                return duplicate;
            }
 
            public abstract bool MoveNext();
 
            public abstract IEnumerable</tsource><tresult> Select</tresult><tresult>(Func</tresult><tsource, tresult=""> selector);
 
            public abstract IEnumerable</tsource,><tsource> Where(Func</tsource><tsource, bool=""> predicate);
 
            object IEnumerator.Current {
                get { return Current; }
            }
  
            IEnumerator IEnumerable.GetEnumerator() {
                return GetEnumerator();
            }
  
            void IEnumerator.Reset() {
                throw new NotImplementedException();
            }
        }
  
        class WhereEnumerableIterator</tsource,><tsource> : Iterator</tsource><tsource>
        {
            IEnumerable</tsource><tsource> source;
            Func</tsource><tsource, bool=""> predicate;
            IEnumerator</tsource,><tsource> enumerator;
  
            public WhereEnumerableIterator(IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
                this.source = source;
                this.predicate = predicate;
            }
 
            public override Iterator</tsource,><tsource> Clone() {
                return new WhereEnumerableIterator</tsource><tsource>(source, predicate);
            }
  
            public override void Dispose() {
                if (enumerator is IDisposable) ((IDisposable)enumerator).Dispose();
                enumerator = null;
                base.Dispose();
            }
 
            public override bool MoveNext() {
                switch (state) {
                    case 1:
                        enumerator = source.GetEnumerator();
                        state = 2;
                        goto case 2;
                    case 2:
                        while (enumerator.MoveNext()) {
                            TSource item = enumerator.Current;
                            if (predicate(item)) {
                                current = item;
                                return true;
                            }
                        }
                        Dispose();
                        break;
                }
                return false;
            }
 
            public override IEnumerable</tsource><tresult> Select</tresult><tresult>(Func</tresult><tsource, tresult=""> selector) {
                return new WhereSelectEnumerableIterator</tsource,><tsource, tresult="">(source, predicate, selector);
            }
  
            public override IEnumerable</tsource,><tsource> Where(Func</tsource><tsource, bool=""> predicate) {
                return new WhereEnumerableIterator</tsource,><tsource>(source, CombinePredicates(this.predicate, predicate));
            }
        }
 
        class WhereArrayIterator</tsource><tsource> : Iterator</tsource><tsource>
        {
            TSource[] source;
            Func</tsource><tsource, bool=""> predicate;
            int index;
 
            public WhereArrayIterator(TSource[] source, Func</tsource,><tsource, bool=""> predicate) {
                this.source = source;
                this.predicate = predicate;
            }
  
            public override Iterator</tsource,><tsource> Clone() {
                return new WhereArrayIterator</tsource><tsource>(source, predicate);
            }
 
            public override bool MoveNext() {
                if (state == 1) {
                    while (index < source.Length) {
                        TSource item = source[index];
                        index++;
                        if (predicate(item)) {
                            current = item;
                            return true;
                        }
                    }
                    Dispose();
                }
                return false;
            }
 
            public override IEnumerable</tsource><tresult> Select</tresult><tresult>(Func</tresult><tsource, tresult=""> selector) {
                return new WhereSelectArrayIterator</tsource,><tsource, tresult="">(source, predicate, selector);
            }
 
            public override IEnumerable</tsource,><tsource> Where(Func</tsource><tsource, bool=""> predicate) {
                return new WhereArrayIterator</tsource,><tsource>(source, CombinePredicates(this.predicate, predicate));
            }
        }
 
        class WhereListIterator</tsource><tsource> : Iterator</tsource><tsource>
        {
            List</tsource><tsource> source;
            Func</tsource><tsource, bool=""> predicate;
            List</tsource,><tsource>.Enumerator enumerator;
 
            public WhereListIterator(List</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
                this.source = source;
                this.predicate = predicate;
            }
 
            public override Iterator</tsource,><tsource> Clone() {
                return new WhereListIterator</tsource><tsource>(source, predicate);
            }
 
            public override bool MoveNext() {
                switch (state) {
                    case 1:
                        enumerator = source.GetEnumerator();
                        state = 2;
                        goto case 2;
                    case 2:
                        while (enumerator.MoveNext()) {
                            TSource item = enumerator.Current;
                            if (predicate(item)) {
                                current = item;
                                return true;
                            }
                        }
                        Dispose();
                        break;
                }
                return false;
            }
  
            public override IEnumerable</tsource><tresult> Select</tresult><tresult>(Func</tresult><tsource, tresult=""> selector) {
                return new WhereSelectListIterator</tsource,><tsource, tresult="">(source, predicate, selector);
            }
 
            public override IEnumerable</tsource,><tsource> Where(Func</tsource><tsource, bool=""> predicate) {
                return new WhereListIterator</tsource,><tsource>(source, CombinePredicates(this.predicate, predicate));
            }
        }
  
        class WhereSelectEnumerableIterator</tsource><tsource, tresult=""> : Iterator</tsource,><tresult>
        {
            IEnumerable</tresult><tsource> source;
            Func</tsource><tsource, bool=""> predicate;
            Func</tsource,><tsource, tresult=""> selector;
            IEnumerator</tsource,><tsource> enumerator;
 
            public WhereSelectEnumerableIterator(IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate, Func</tsource,><tsource, tresult=""> selector) {
                this.source = source;
                this.predicate = predicate;
                this.selector = selector;
            }
 
            public override Iterator</tsource,><tresult> Clone() {
                return new WhereSelectEnumerableIterator</tresult><tsource, tresult="">(source, predicate, selector);
            }
  
            public override void Dispose() {
                if (enumerator is IDisposable) ((IDisposable)enumerator).Dispose();
                enumerator = null;
                base.Dispose();
            }
 
            public override bool MoveNext() {
                switch (state) {
                    case 1:
                        enumerator = source.GetEnumerator();
                        state = 2;
                        goto case 2;
                    case 2:
                        while (enumerator.MoveNext()) {
                            TSource item = enumerator.Current;
                            if (predicate == null || predicate(item)) {
                                current = selector(item);
                                return true;
                            }
                        }
                        Dispose();
                        break;
                }
                return false;
            }
 
            public override IEnumerable</tsource,><tresult2> Select</tresult2><tresult2>(Func</tresult2><tresult, tresult2=""> selector) {
                return new WhereSelectEnumerableIterator</tresult,><tsource, tresult2="">(source, predicate, CombineSelectors(this.selector, selector));
            }
  
            public override IEnumerable</tsource,><tresult> Where(Func</tresult><tresult, bool=""> predicate) {
                return new WhereEnumerableIterator</tresult,><tresult>(this, predicate);
            }
        }
 
        class WhereSelectArrayIterator</tresult><tsource, tresult=""> : Iterator</tsource,><tresult>
        {
            TSource[] source;
            Func</tresult><tsource, bool=""> predicate;
            Func</tsource,><tsource, tresult=""> selector;
            int index;
 
            public WhereSelectArrayIterator(TSource[] source, Func</tsource,><tsource, bool=""> predicate, Func</tsource,><tsource, tresult=""> selector) {
                this.source = source;
                this.predicate = predicate;
                this.selector = selector;
            }
  
            public override Iterator</tsource,><tresult> Clone() {
                return new WhereSelectArrayIterator</tresult><tsource, tresult="">(source, predicate, selector);
            }
  
            public override bool MoveNext() {
                if (state == 1) {
                    while (index < source.Length) {
                        TSource item = source[index];
                        index++;
                        if (predicate == null || predicate(item)) {
                            current = selector(item);
                            return true;
                        }
                    }
                    Dispose();
                }
                return false;
            }
 
            public override IEnumerable</tsource,><tresult2> Select</tresult2><tresult2>(Func</tresult2><tresult, tresult2=""> selector) {
                return new WhereSelectArrayIterator</tresult,><tsource, tresult2="">(source, predicate, CombineSelectors(this.selector, selector));
            }
 
            public override IEnumerable</tsource,><tresult> Where(Func</tresult><tresult, bool=""> predicate) {
                return new WhereEnumerableIterator</tresult,><tresult>(this, predicate);
            }
        }
 
        class WhereSelectListIterator</tresult><tsource, tresult=""> : Iterator</tsource,><tresult>
        {
            List</tresult><tsource> source;
            Func</tsource><tsource, bool=""> predicate;
            Func</tsource,><tsource, tresult=""> selector;
            List</tsource,><tsource>.Enumerator enumerator;
 
            public WhereSelectListIterator(List</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate, Func</tsource,><tsource, tresult=""> selector) {
                this.source = source;
                this.predicate = predicate;
                this.selector = selector;
            }
 
            public override Iterator</tsource,><tresult> Clone() {
                return new WhereSelectListIterator</tresult><tsource, tresult="">(source, predicate, selector);
            }
  
            public override bool MoveNext() {
                switch (state) {
                    case 1:
                        enumerator = source.GetEnumerator();
                        state = 2;
                        goto case 2;
                    case 2:
                        while (enumerator.MoveNext()) {
                            TSource item = enumerator.Current;
                            if (predicate == null || predicate(item)) {
                                current = selector(item);
                                return true;
                            }
                        }
                        Dispose();
                        break;
                }
                return false;
            }
 
            public override IEnumerable</tsource,><tresult2> Select</tresult2><tresult2>(Func</tresult2><tresult, tresult2=""> selector) {
                return new WhereSelectListIterator</tresult,><tsource, tresult2="">(source, predicate, CombineSelectors(this.selector, selector));
            }
  
            public override IEnumerable</tsource,><tresult> Where(Func</tresult><tresult, bool=""> predicate) {
                return new WhereEnumerableIterator</tresult,><tresult>(this, predicate);
            }
        }
 
        //public static IEnumerable</tresult><tsource> Where</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
        //    if (source == null) throw Error.ArgumentNull("source");
        //    if (predicate == null) throw Error.ArgumentNull("predicate");
        //    return WhereIterator</tsource,><tsource>(source, predicate);
        //}
 
        //static IEnumerable</tsource><tsource> WhereIterator</tsource><tsource>(IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
        //    foreach (TSource element in source) {
        //        if (predicate(element)) yield return element;
        //    }
        //}
 
        //public static IEnumerable</tsource,><tresult> Select</tresult><tsource, tresult="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tresult=""> selector) {
        //    if (source == null) throw Error.ArgumentNull("source");
        //    if (selector == null) throw Error.ArgumentNull("selector");
        //    return SelectIterator</tsource,><tsource, tresult="">(source, selector);
        //}
 
        //static IEnumerable</tsource,><tresult> SelectIterator</tresult><tsource, tresult="">(IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tresult=""> selector) {
        //    foreach (TSource element in source) {
        //        yield return selector(element);
        //    }
        //}
 
        public static IEnumerable</tsource,><tresult> SelectMany</tresult><tsource, tresult="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, ienumerable<tresult="">> selector) {
            if (source == null) throw Error.ArgumentNull("source");
            if (selector == null) throw Error.ArgumentNull("selector");
            return SelectManyIterator</tsource,><tsource, tresult="">(source, selector);
        }
 
        static IEnumerable</tsource,><tresult> SelectManyIterator</tresult><tsource, tresult="">(IEnumerable</tsource,><tsource> source, Func</tsource><tsource, ienumerable<tresult="">> selector) {
            foreach (TSource element in source) {
                foreach (TResult subElement in selector(element)) {
                    yield return subElement;
                }
            }
        }
  
        public static IEnumerable</tsource,><tresult> SelectMany</tresult><tsource, tresult="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, int,="" ienumerable<tresult="">> selector) {
            if (source == null) throw Error.ArgumentNull("source");
            if (selector == null) throw Error.ArgumentNull("selector");
            return SelectManyIterator</tsource,><tsource, tresult="">(source, selector);
        }
 
        static IEnumerable</tsource,><tresult> SelectManyIterator</tresult><tsource, tresult="">(IEnumerable</tsource,><tsource> source, Func</tsource><tsource, int,="" ienumerable<tresult="">> selector) {
            int index = -1;
            foreach (TSource element in source) {
                checked { index++; }
                foreach (TResult subElement in selector(element, index)) {
                    yield return subElement;
                }
            }
        }
        public static IEnumerable</tsource,><tresult> SelectMany</tresult><tsource, tcollection,="" tresult="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, int,="" ienumerable<tcollection="">> collectionSelector, Func</tsource,><tsource, tcollection,="" tresult=""> resultSelector)
        {
            if (source == null) throw Error.ArgumentNull("source");
            if (collectionSelector == null) throw Error.ArgumentNull("collectionSelector");
            if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
            return SelectManyIterator</tsource,><tsource, tcollection,="" tresult="">(source, collectionSelector, resultSelector);
        }
  
        static IEnumerable</tsource,><tresult> SelectManyIterator</tresult><tsource, tcollection,="" tresult="">(IEnumerable</tsource,><tsource> source, Func</tsource><tsource, int,="" ienumerable<tcollection="">> collectionSelector, Func</tsource,><tsource, tcollection,="" tresult=""> resultSelector){
            int index = -1;
            foreach (TSource element in source){
                checked { index++; }
                foreach (TCollection subElement in collectionSelector(element, index)){
                    yield return resultSelector(element, subElement);
                }
            }
        }
 
        public static IEnumerable</tsource,><tresult> SelectMany</tresult><tsource, tcollection,="" tresult="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, ienumerable<tcollection="">> collectionSelector, Func</tsource,><tsource, tcollection,="" tresult=""> resultSelector) {
            if (source == null) throw Error.ArgumentNull("source");
            if (collectionSelector == null) throw Error.ArgumentNull("collectionSelector");
            if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
            return SelectManyIterator</tsource,><tsource, tcollection,="" tresult="">(source, collectionSelector, resultSelector);
        }
 
        static IEnumerable</tsource,><tresult> SelectManyIterator</tresult><tsource, tcollection,="" tresult="">(IEnumerable</tsource,><tsource> source, Func</tsource><tsource, ienumerable<tcollection="">> collectionSelector, Func</tsource,><tsource, tcollection,="" tresult=""> resultSelector) {
            foreach (TSource element in source) {
                foreach (TCollection subElement in collectionSelector(element)) {
                    yield return resultSelector(element, subElement);
                }
            }
        }
  
        public static IEnumerable</tsource,><tsource> Take</tsource><tsource>(this IEnumerable</tsource><tsource> source, int count) {
            if (source == null) throw Error.ArgumentNull("source");
            return TakeIterator</tsource><tsource>(source, count);
        }
 
        static IEnumerable</tsource><tsource> TakeIterator</tsource><tsource>(IEnumerable</tsource><tsource> source, int count) {
            if (count > 0) {
                foreach (TSource element in source) {
                    yield return element;
                    if (--count == 0) break;
                }
            }
        }
 
        public static IEnumerable</tsource><tsource> TakeWhile</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            return TakeWhileIterator</tsource,><tsource>(source, predicate);
        }
  
        static IEnumerable</tsource><tsource> TakeWhileIterator</tsource><tsource>(IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            foreach (TSource element in source) {
                if (!predicate(element)) break;
                yield return element;
            }
        }
  
        public static IEnumerable</tsource,><tsource> TakeWhile</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, int,="" bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            return TakeWhileIterator</tsource,><tsource>(source, predicate);
        }
  
        static IEnumerable</tsource><tsource> TakeWhileIterator</tsource><tsource>(IEnumerable</tsource><tsource> source, Func</tsource><tsource, int,="" bool=""> predicate) {
            int index = -1;
            foreach (TSource element in source) {
                checked { index++; }
                if (!predicate(element, index)) break;
                yield return element;
            }
        }
  
        public static IEnumerable</tsource,><tsource> Skip</tsource><tsource>(this IEnumerable</tsource><tsource> source, int count) {
            if (source == null) throw Error.ArgumentNull("source");
            return SkipIterator</tsource><tsource>(source, count);
        }
  
        static IEnumerable</tsource><tsource> SkipIterator</tsource><tsource>(IEnumerable</tsource><tsource> source, int count) {
            using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                while (count > 0 && e.MoveNext()) count--;
                if (count <= 0) {
                    while (e.MoveNext()) yield return e.Current;
                }
            }
        }
  
        public static IEnumerable</tsource><tsource> SkipWhile</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            return SkipWhileIterator</tsource,><tsource>(source, predicate);
        }
  
        static IEnumerable</tsource><tsource> SkipWhileIterator</tsource><tsource>(IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            bool yielding = false;
            foreach (TSource element in source) {
                if (!yielding && !predicate(element)) yielding = true;
                if (yielding) yield return element;
            }
        }
 
        public static IEnumerable</tsource,><tsource> SkipWhile</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, int,="" bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            return SkipWhileIterator</tsource,><tsource>(source, predicate);
        }
 
        static IEnumerable</tsource><tsource> SkipWhileIterator</tsource><tsource>(IEnumerable</tsource><tsource> source, Func</tsource><tsource, int,="" bool=""> predicate) {
            int index = -1;
            bool yielding = false;
            foreach (TSource element in source) {
                checked { index++; }
                if (!yielding && !predicate(element, index)) yielding = true;
                if (yielding) yield return element;
            }
        }
 
        public static IEnumerable</tsource,><tresult> Join</tresult><touter, tinner,="" tkey,="" tresult="">(this IEnumerable</touter,><touter> outer, IEnumerable</touter><tinner> inner, Func</tinner><touter, tkey=""> outerKeySelector, Func</touter,><tinner, tkey=""> innerKeySelector, Func</tinner,><touter, tinner,="" tresult=""> resultSelector) {
            if (outer == null) throw Error.ArgumentNull("outer");
            if (inner == null) throw Error.ArgumentNull("inner");
            if (outerKeySelector == null) throw Error.ArgumentNull("outerKeySelector");
            if (innerKeySelector == null) throw Error.ArgumentNull("innerKeySelector");
            if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
            return JoinIterator</touter,><touter, tinner,="" tkey,="" tresult="">(outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
        }
 
        public static IEnumerable</touter,><tresult> Join</tresult><touter, tinner,="" tkey,="" tresult="">(this IEnumerable</touter,><touter> outer, IEnumerable</touter><tinner> inner, Func</tinner><touter, tkey=""> outerKeySelector, Func</touter,><tinner, tkey=""> innerKeySelector, Func</tinner,><touter, tinner,="" tresult=""> resultSelector, IEqualityComparer</touter,><tkey> comparer) {
            if (outer == null) throw Error.ArgumentNull("outer");
            if (inner == null) throw Error.ArgumentNull("inner");
            if (outerKeySelector == null) throw Error.ArgumentNull("outerKeySelector");
            if (innerKeySelector == null) throw Error.ArgumentNull("innerKeySelector");
            if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
            return JoinIterator</tkey><touter, tinner,="" tkey,="" tresult="">(outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
        }
 
        static IEnumerable</touter,><tresult> JoinIterator</tresult><touter, tinner,="" tkey,="" tresult="">(IEnumerable</touter,><touter> outer, IEnumerable</touter><tinner> inner, Func</tinner><touter, tkey=""> outerKeySelector, Func</touter,><tinner, tkey=""> innerKeySelector, Func</tinner,><touter, tinner,="" tresult=""> resultSelector, IEqualityComparer</touter,><tkey> comparer) {
            Lookup</tkey><tkey, tinner=""> lookup = Lookup</tkey,><tkey, tinner="">.CreateForJoin(inner, innerKeySelector, comparer);
            foreach (TOuter item in outer) {
                Lookup</tkey,><tkey, tinner="">.Grouping g = lookup.GetGrouping(outerKeySelector(item), false);
                if (g != null) {
                    for (int i = 0; i < g.count; i++) {
                        yield return resultSelector(item, g.elements[i]);
                    }
                }
            }
        }
  
        public static IEnumerable</tkey,><tresult> GroupJoin</tresult><touter, tinner,="" tkey,="" tresult="">(this IEnumerable</touter,><touter> outer, IEnumerable</touter><tinner> inner, Func</tinner><touter, tkey=""> outerKeySelector, Func</touter,><tinner, tkey=""> innerKeySelector, Func</tinner,><touter, ienumerable<tinner="">, TResult> resultSelector) {
            if (outer == null) throw Error.ArgumentNull("outer");
            if (inner == null) throw Error.ArgumentNull("inner");
            if (outerKeySelector == null) throw Error.ArgumentNull("outerKeySelector");
            if (innerKeySelector == null) throw Error.ArgumentNull("innerKeySelector");
            if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
            return GroupJoinIterator</touter,><touter, tinner,="" tkey,="" tresult="">(outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
        }
  
        public static IEnumerable</touter,><tresult> GroupJoin</tresult><touter, tinner,="" tkey,="" tresult="">(this IEnumerable</touter,><touter> outer, IEnumerable</touter><tinner> inner, Func</tinner><touter, tkey=""> outerKeySelector, Func</touter,><tinner, tkey=""> innerKeySelector, Func</tinner,><touter, ienumerable<tinner="">, TResult> resultSelector, IEqualityComparer</touter,><tkey> comparer) {
            if (outer == null) throw Error.ArgumentNull("outer");
            if (inner == null) throw Error.ArgumentNull("inner");
            if (outerKeySelector == null) throw Error.ArgumentNull("outerKeySelector");
            if (innerKeySelector == null) throw Error.ArgumentNull("innerKeySelector");
            if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
            return GroupJoinIterator</tkey><touter, tinner,="" tkey,="" tresult="">(outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
        }
  
        static IEnumerable</touter,><tresult> GroupJoinIterator</tresult><touter, tinner,="" tkey,="" tresult="">(IEnumerable</touter,><touter> outer, IEnumerable</touter><tinner> inner, Func</tinner><touter, tkey=""> outerKeySelector, Func</touter,><tinner, tkey=""> innerKeySelector, Func</tinner,><touter, ienumerable<tinner="">, TResult> resultSelector, IEqualityComparer</touter,><tkey> comparer) {
            Lookup</tkey><tkey, tinner=""> lookup = Lookup</tkey,><tkey, tinner="">.CreateForJoin(inner, innerKeySelector, comparer);
            foreach (TOuter item in outer) {
                yield return resultSelector(item, lookup[outerKeySelector(item)]);
            }
        }
  
        public static IOrderedEnumerable</tkey,><tsource> OrderBy</tsource><tsource, tkey="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector) {
            return new OrderedEnumerable</tsource,><tsource, tkey="">(source, keySelector, null, false);
        }
 
        public static IOrderedEnumerable</tsource,><tsource> OrderBy</tsource><tsource, tkey="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, IComparer</tsource,><tkey> comparer) {
            return new OrderedEnumerable</tkey><tsource, tkey="">(source, keySelector, comparer, false);
        }
 
        public static IOrderedEnumerable</tsource,><tsource> OrderByDescending</tsource><tsource, tkey="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector) {
            return new OrderedEnumerable</tsource,><tsource, tkey="">(source, keySelector, null, true);
        }
  
        public static IOrderedEnumerable</tsource,><tsource> OrderByDescending</tsource><tsource, tkey="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, IComparer</tsource,><tkey> comparer) {
            return new OrderedEnumerable</tkey><tsource, tkey="">(source, keySelector, comparer, true);
        }
 
        public static IOrderedEnumerable</tsource,><tsource> ThenBy</tsource><tsource, tkey="">(this IOrderedEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector) {
            if (source == null) throw Error.ArgumentNull("source");
            return source.CreateOrderedEnumerable</tsource,><tkey>(keySelector, null, false);
        }
  
        public static IOrderedEnumerable</tkey><tsource> ThenBy</tsource><tsource, tkey="">(this IOrderedEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, IComparer</tsource,><tkey> comparer) {
            if (source == null) throw Error.ArgumentNull("source");
            return source.CreateOrderedEnumerable</tkey><tkey>(keySelector, comparer, false);
        }
 
        public static IOrderedEnumerable</tkey><tsource> ThenByDescending</tsource><tsource, tkey="">(this IOrderedEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector) {
            if (source == null) throw Error.ArgumentNull("source");
            return source.CreateOrderedEnumerable</tsource,><tkey>(keySelector, null, true);
        }
 
        public static IOrderedEnumerable</tkey><tsource> ThenByDescending</tsource><tsource, tkey="">(this IOrderedEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, IComparer</tsource,><tkey> comparer) {
            if (source == null) throw Error.ArgumentNull("source");
            return source.CreateOrderedEnumerable</tkey><tkey>(keySelector, comparer, true);
        }
  
        public static IEnumerable</tkey><igrouping<tkey, tsource="">> GroupBy</igrouping<tkey,><tsource, tkey="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector) {
            return new GroupedEnumerable</tsource,><tsource, tkey,="" tsource="">(source, keySelector, IdentityFunction</tsource,><tsource>.Instance, null);
        }
 
        public static IEnumerable</tsource><igrouping<tkey, tsource="">> GroupBy</igrouping<tkey,><tsource, tkey="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, IEqualityComparer</tsource,><tkey> comparer) {
            return new GroupedEnumerable</tkey><tsource, tkey,="" tsource="">(source, keySelector, IdentityFunction</tsource,><tsource>.Instance, comparer);
        }
 
        public static IEnumerable</tsource><igrouping<tkey, telement="">> GroupBy</igrouping<tkey,><tsource, tkey,="" telement="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, Func</tsource,><tsource, telement=""> elementSelector) {
            return new GroupedEnumerable</tsource,><tsource, tkey,="" telement="">(source, keySelector, elementSelector, null);
        }
  
        public static IEnumerable</tsource,><igrouping<tkey, telement="">> GroupBy</igrouping<tkey,><tsource, tkey,="" telement="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, Func</tsource,><tsource, telement=""> elementSelector, IEqualityComparer</tsource,><tkey> comparer) {
            return new GroupedEnumerable</tkey><tsource, tkey,="" telement="">(source, keySelector, elementSelector, comparer);
        }
 
       public static IEnumerable</tsource,><tresult> GroupBy</tresult><tsource, tkey,="" tresult="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, Func</tsource,><tkey, ienumerable<tsource="">, TResult> resultSelector){
           return  new GroupedEnumerable</tkey,><tsource, tkey,="" tsource,="" tresult="">(source, keySelector, IdentityFunction</tsource,><tsource>.Instance, resultSelector, null);
        }
  
        public static IEnumerable</tsource><tresult> GroupBy</tresult><tsource, tkey,="" telement,="" tresult="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, Func</tsource,><tsource, telement=""> elementSelector, Func</tsource,><tkey, ienumerable<telement="">, TResult> resultSelector){
           return new GroupedEnumerable</tkey,><tsource, tkey,="" telement,="" tresult="">(source, keySelector, elementSelector, resultSelector, null);
        }
 
        public static IEnumerable</tsource,><tresult> GroupBy</tresult><tsource, tkey,="" tresult="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, Func</tsource,><tkey, ienumerable<tsource="">, TResult> resultSelector, IEqualityComparer</tkey,><tkey> comparer){
            return  new GroupedEnumerable</tkey><tsource, tkey,="" tsource,="" tresult="">(source, keySelector, IdentityFunction</tsource,><tsource>.Instance, resultSelector, comparer);
        }
 
        public static IEnumerable</tsource><tresult> GroupBy</tresult><tsource, tkey,="" telement,="" tresult="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, Func</tsource,><tsource, telement=""> elementSelector, Func</tsource,><tkey, ienumerable<telement="">, TResult> resultSelector, IEqualityComparer</tkey,><tkey> comparer){
            return  new GroupedEnumerable</tkey><tsource, tkey,="" telement,="" tresult="">(source, keySelector, elementSelector, resultSelector, comparer);
        }
  
        public static IEnumerable</tsource,><tsource> Concat</tsource><tsource>(this IEnumerable</tsource><tsource> first, IEnumerable</tsource><tsource> second) {
            if (first == null) throw Error.ArgumentNull("first");
            if (second == null) throw Error.ArgumentNull("second");
            return ConcatIterator</tsource><tsource>(first, second);
        }
  
        static IEnumerable</tsource><tsource> ConcatIterator</tsource><tsource>(IEnumerable</tsource><tsource> first, IEnumerable</tsource><tsource> second) {
            foreach (TSource element in first) yield return element;
            foreach (TSource element in second) yield return element;
        }
 
        public static IEnumerable</tsource><tresult> Zip</tresult><tfirst, tsecond,="" tresult="">(this IEnumerable</tfirst,><tfirst> first, IEnumerable</tfirst><tsecond> second, Func</tsecond><tfirst, tsecond,="" tresult=""> resultSelector) {
            if (first == null) throw Error.ArgumentNull("first");
            if (second == null) throw Error.ArgumentNull("second");
            if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
            return ZipIterator(first, second, resultSelector);
        }
  
        static IEnumerable</tfirst,><tresult> ZipIterator</tresult><tfirst, tsecond,="" tresult="">(IEnumerable</tfirst,><tfirst> first, IEnumerable</tfirst><tsecond> second, Func</tsecond><tfirst, tsecond,="" tresult=""> resultSelector) {
            using (IEnumerator</tfirst,><tfirst> e1 = first.GetEnumerator())
                using (IEnumerator</tfirst><tsecond> e2 = second.GetEnumerator())
                    while (e1.MoveNext() && e2.MoveNext())
                        yield return resultSelector(e1.Current, e2.Current);
        }
  
 
        public static IEnumerable</tsecond><tsource> Distinct</tsource><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            return DistinctIterator</tsource><tsource>(source, null);
        }
  
        public static IEnumerable</tsource><tsource> Distinct</tsource><tsource>(this IEnumerable</tsource><tsource> source, IEqualityComparer</tsource><tsource> comparer) {
            if (source == null) throw Error.ArgumentNull("source");
            return DistinctIterator</tsource><tsource>(source, comparer);
        }
  
        static IEnumerable</tsource><tsource> DistinctIterator</tsource><tsource>(IEnumerable</tsource><tsource> source, IEqualityComparer</tsource><tsource> comparer) {
            Set</tsource><tsource> set = new Set</tsource><tsource>(comparer);
            foreach (TSource element in source)
                if (set.Add(element)) yield return element;
        }
  
        public static IEnumerable</tsource><tsource> Union</tsource><tsource>(this IEnumerable</tsource><tsource> first, IEnumerable</tsource><tsource> second) {
            if (first == null) throw Error.ArgumentNull("first");
            if (second == null) throw Error.ArgumentNull("second");
            return UnionIterator</tsource><tsource>(first, second, null);
        }
 
        public static IEnumerable</tsource><tsource> Union</tsource><tsource>(this IEnumerable</tsource><tsource> first, IEnumerable</tsource><tsource> second, IEqualityComparer</tsource><tsource> comparer)
        {
            if (first == null) throw Error.ArgumentNull("first");
            if (second == null) throw Error.ArgumentNull("second");
            return UnionIterator</tsource><tsource>(first, second, comparer);
        }
 
        static IEnumerable</tsource><tsource> UnionIterator</tsource><tsource>(IEnumerable</tsource><tsource> first, IEnumerable</tsource><tsource> second, IEqualityComparer</tsource><tsource> comparer)
        {
            Set</tsource><tsource> set = new Set</tsource><tsource>(comparer);
            foreach (TSource element in first)
                if (set.Add(element)) yield return element;
            foreach (TSource element in second)
                if (set.Add(element)) yield return element;
        }
 
        public static IEnumerable</tsource><tsource> Intersect</tsource><tsource>(this IEnumerable</tsource><tsource> first, IEnumerable</tsource><tsource> second) {
            if (first == null) throw Error.ArgumentNull("first");
            if (second == null) throw Error.ArgumentNull("second");
            return IntersectIterator</tsource><tsource>(first, second, null);
        }
  
        public static IEnumerable</tsource><tsource> Intersect</tsource><tsource>(this IEnumerable</tsource><tsource> first, IEnumerable</tsource><tsource> second, IEqualityComparer</tsource><tsource> comparer)
        {
            if (first == null) throw Error.ArgumentNull("first");
            if (second == null) throw Error.ArgumentNull("second");
            return IntersectIterator</tsource><tsource>(first, second, comparer);
        }
 
        static IEnumerable</tsource><tsource> IntersectIterator</tsource><tsource>(IEnumerable</tsource><tsource> first, IEnumerable</tsource><tsource> second, IEqualityComparer</tsource><tsource> comparer)
        {
            Set</tsource><tsource> set = new Set</tsource><tsource>(comparer);
            foreach (TSource element in second) set.Add(element);
            foreach (TSource element in first)
                if (set.Remove(element)) yield return element;
        }
  
        public static IEnumerable</tsource><tsource> Except</tsource><tsource>(this IEnumerable</tsource><tsource> first, IEnumerable</tsource><tsource> second)
        {
            if (first == null) throw Error.ArgumentNull("first");
            if (second == null) throw Error.ArgumentNull("second");
            return ExceptIterator</tsource><tsource>(first, second, null);
        }
 
        public static IEnumerable</tsource><tsource> Except</tsource><tsource>(this IEnumerable</tsource><tsource> first, IEnumerable</tsource><tsource> second, IEqualityComparer</tsource><tsource> comparer)
        {
            if (first == null) throw Error.ArgumentNull("first");
            if (second == null) throw Error.ArgumentNull("second");
            return ExceptIterator</tsource><tsource>(first, second, comparer);
        }
  
        static IEnumerable</tsource><tsource> ExceptIterator</tsource><tsource>(IEnumerable</tsource><tsource> first, IEnumerable</tsource><tsource> second, IEqualityComparer</tsource><tsource> comparer) {
            Set</tsource><tsource> set = new Set</tsource><tsource>(comparer);
            foreach (TSource element in second) set.Add(element);
            foreach (TSource element in first)
                if (set.Add(element)) yield return element;
        }
  
        public static IEnumerable</tsource><tsource> Reverse</tsource><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            return ReverseIterator</tsource><tsource>(source);
        }
 
        static IEnumerable</tsource><tsource> ReverseIterator</tsource><tsource>(IEnumerable</tsource><tsource> source) {
            Buffer</tsource><tsource> buffer = new Buffer</tsource><tsource>(source);
            for (int i = buffer.count - 1; i >= 0; i--) yield return buffer.items[i];
        }
 
        public static bool SequenceEqual</tsource><tsource>(this IEnumerable</tsource><tsource> first, IEnumerable</tsource><tsource> second) {
            return SequenceEqual</tsource><tsource>(first, second, null);
        }
 
        public static bool SequenceEqual</tsource><tsource>(this IEnumerable</tsource><tsource> first, IEnumerable</tsource><tsource> second, IEqualityComparer</tsource><tsource> comparer)
        {
            if (comparer == null) comparer = EqualityComparer</tsource><tsource>.Default;
            if (first == null) throw Error.ArgumentNull("first");
            if (second == null) throw Error.ArgumentNull("second");
            using (IEnumerator</tsource><tsource> e1 = first.GetEnumerator())
            using (IEnumerator</tsource><tsource> e2 = second.GetEnumerator())
            {
                while (e1.MoveNext())
                {
                    if (!(e2.MoveNext() && comparer.Equals(e1.Current, e2.Current))) return false;
                }
                if (e2.MoveNext()) return false;
            }
            return true;
        }
 
        public static IEnumerable</tsource><tsource> AsEnumerable</tsource><tsource>(this IEnumerable</tsource><tsource> source)
        {
            return source;
        }
  
        public static TSource[] ToArray</tsource><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            return new Buffer</tsource><tsource>(source).ToArray();
        }
 
        public static List</tsource><tsource> ToList</tsource><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            return new List</tsource><tsource>(source);
        }
 
        public static Dictionary</tsource><tkey, tsource=""> ToDictionary</tkey,><tsource, tkey="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector) {
            return ToDictionary</tsource,><tsource, tkey,="" tsource="">(source, keySelector, IdentityFunction</tsource,><tsource>.Instance, null);
        }
 
        public static Dictionary</tsource><tkey, tsource=""> ToDictionary</tkey,><tsource, tkey="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, IEqualityComparer</tsource,><tkey> comparer) {
            return ToDictionary</tkey><tsource, tkey,="" tsource="">(source, keySelector, IdentityFunction</tsource,><tsource>.Instance, comparer);
        }
  
        public static Dictionary</tsource><tkey, telement=""> ToDictionary</tkey,><tsource, tkey,="" telement="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, Func</tsource,><tsource, telement=""> elementSelector) {
            return ToDictionary</tsource,><tsource, tkey,="" telement="">(source, keySelector, elementSelector, null);
        }
 
        public static Dictionary</tsource,><tkey, telement=""> ToDictionary</tkey,><tsource, tkey,="" telement="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, Func</tsource,><tsource, telement=""> elementSelector, IEqualityComparer</tsource,><tkey> comparer) {
            if (source == null) throw Error.ArgumentNull("source");
            if (keySelector == null) throw Error.ArgumentNull("keySelector");
            if (elementSelector == null) throw Error.ArgumentNull("elementSelector");
            Dictionary</tkey><tkey, telement=""> d = new Dictionary</tkey,><tkey, telement="">(comparer);
            foreach (TSource element in source) d.Add(keySelector(element), elementSelector(element));
            return d;
        }
 
        public static ILookup</tkey,><tkey, tsource=""> ToLookup</tkey,><tsource, tkey="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector) {
            return Lookup</tsource,><tkey, tsource="">.Create(source, keySelector, IdentityFunction</tkey,><tsource>.Instance, null);
        }
  
        public static ILookup</tsource><tkey, tsource=""> ToLookup</tkey,><tsource, tkey="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, IEqualityComparer</tsource,><tkey> comparer) {
            return Lookup</tkey><tkey, tsource="">.Create(source, keySelector, IdentityFunction</tkey,><tsource>.Instance, comparer);
        }
 
        public static ILookup</tsource><tkey, telement=""> ToLookup</tkey,><tsource, tkey,="" telement="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, Func</tsource,><tsource, telement=""> elementSelector) {
            return Lookup</tsource,><tkey, telement="">.Create(source, keySelector, elementSelector, null);
        }
 
        public static ILookup</tkey,><tkey, telement=""> ToLookup</tkey,><tsource, tkey,="" telement="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, Func</tsource,><tsource, telement=""> elementSelector, IEqualityComparer</tsource,><tkey> comparer) {
            return Lookup</tkey><tkey, telement="">.Create(source, keySelector, elementSelector, comparer);
        }
  
        public static IEnumerable</tkey,><tsource> DefaultIfEmpty</tsource><tsource>(this IEnumerable</tsource><tsource> source) {
            return DefaultIfEmpty(source, default(TSource));
        }
  
        public static IEnumerable</tsource><tsource> DefaultIfEmpty</tsource><tsource>(this IEnumerable</tsource><tsource> source, TSource defaultValue) {
            if (source == null) throw Error.ArgumentNull("source");
            return DefaultIfEmptyIterator</tsource><tsource>(source, defaultValue);
        }
  
        static IEnumerable</tsource><tsource> DefaultIfEmptyIterator</tsource><tsource>(IEnumerable</tsource><tsource> source, TSource defaultValue) {
            using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                if (e.MoveNext()) {
                    do {
                        yield return e.Current;
                    } while (e.MoveNext());
                }
                else {
                    yield return defaultValue;
                }
            }
        }
  
        public static IEnumerable</tsource><tresult> OfType</tresult><tresult>(this IEnumerable source) {
            if (source == null) throw Error.ArgumentNull("source");
            return OfTypeIterator</tresult><tresult>(source);
        }
  
        static IEnumerable</tresult><tresult> OfTypeIterator</tresult><tresult>(IEnumerable source) {
            foreach (object obj in source) {
                if (obj is TResult) yield return (TResult)obj;
            }
        }
  
        public static IEnumerable</tresult><tresult> Cast</tresult><tresult>(this IEnumerable source) {
            IEnumerable</tresult><tresult> typedSource = source as IEnumerable</tresult><tresult>;
            if (typedSource != null) return typedSource;
            if (source == null) throw Error.ArgumentNull("source");
            return CastIterator</tresult><tresult>(source);
        }
  
        static IEnumerable</tresult><tresult> CastIterator</tresult><tresult>(IEnumerable source) {
            foreach (object obj in source) yield return (TResult)obj;
        }
 
        public static TSource First</tresult><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            IList</tsource><tsource> list = source as IList</tsource><tsource>;
            if (list != null) {
                if (list.Count > 0) return list[0];
            }
            else {
                using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                    if (e.MoveNext()) return e.Current;
                }
            }
            throw Error.NoElements();
        }
  
        public static TSource First</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            foreach (TSource element in source) {
                if (predicate(element)) return element;
            }
            throw Error.NoMatch();
        }
  
        public static TSource FirstOrDefault</tsource,><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            IList</tsource><tsource> list = source as IList</tsource><tsource>;
            if (list != null) {
                if (list.Count > 0) return list[0];
            }
            else {
                using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                    if (e.MoveNext()) return e.Current;
                }
            }
            return default(TSource);
        }
  
        public static TSource FirstOrDefault</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            foreach (TSource element in source) {
                if (predicate(element)) return element;
            }
            return default(TSource);
        }
  
        public static TSource Last</tsource,><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            IList</tsource><tsource> list = source as IList</tsource><tsource>;
            if (list != null) {
                int count = list.Count;
                if (count > 0) return list[count - 1];
            }
            else {
                using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                    if (e.MoveNext()) {
                        TSource result;
                        do {
                            result = e.Current;
                        } while (e.MoveNext());
                        return result;
                    }
                }
            }
            throw Error.NoElements();
        }
 
        public static TSource Last</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            TSource result = default(TSource);
            bool found = false;
            foreach (TSource element in source) {
                if (predicate(element)) {
                    result = element;
                    found = true;
                }
            }
            if (found) return result;
            throw Error.NoMatch();
        }
  
        public static TSource LastOrDefault</tsource,><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            IList</tsource><tsource> list = source as IList</tsource><tsource>;
            if (list != null) {
                int count = list.Count;
                if (count > 0) return list[count - 1];
            }
            else {
                using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                    if (e.MoveNext()) {
                        TSource result;
                        do {
                            result = e.Current;
                        } while (e.MoveNext());
                        return result;
                    }
                }
            }
            return default(TSource);
        }
 
        public static TSource LastOrDefault</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            TSource result = default(TSource);
            foreach (TSource element in source) {
                if (predicate(element)) {
                    result = element;
                }
            }
            return result;
        }
  
        public static TSource Single</tsource,><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            IList</tsource><tsource> list = source as IList</tsource><tsource>;
            if (list != null) {
                switch (list.Count) {
                    case 0: throw Error.NoElements();
                    case 1: return list[0];
                }
            }
            else {
                using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                    if (!e.MoveNext()) throw Error.NoElements();
                    TSource result = e.Current;
                    if (!e.MoveNext()) return result;
                }
            }
            throw Error.MoreThanOneElement();
        }
  
        public static TSource Single</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            TSource result = default(TSource);
            long count = 0;
            foreach (TSource element in source) {
                if (predicate(element)) {
                    result = element;
                    checked { count++; }
                }
            }
            switch (count) {
                case 0: throw Error.NoMatch();
                case 1: return result;
            }
            throw Error.MoreThanOneMatch();
        }
  
        public static TSource SingleOrDefault</tsource,><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            IList</tsource><tsource> list = source as IList</tsource><tsource>;
            if (list != null) {
                switch (list.Count) {
                    case 0: return default(TSource);
                    case 1: return list[0];
                }
            }
            else {
                using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                    if (!e.MoveNext()) return default(TSource);
                    TSource result = e.Current;
                    if (!e.MoveNext()) return result;
                }
            }
            throw Error.MoreThanOneElement();
        }
 
        public static TSource SingleOrDefault</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            TSource result = default(TSource);
            long count = 0;
            foreach (TSource element in source) {
                if (predicate(element)) {
                    result = element;
                    checked { count++; }
                }
            }
            switch (count) {
                case 0: return default(TSource);
                case 1: return result;
            }
            throw Error.MoreThanOneMatch();
        }
 
        public static TSource ElementAt</tsource,><tsource>(this IEnumerable</tsource><tsource> source, int index) {
            if (source == null) throw Error.ArgumentNull("source");
            IList</tsource><tsource> list = source as IList</tsource><tsource>;
            if (list != null) return list[index];
            if (index < 0) throw Error.ArgumentOutOfRange("index");
            using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                while (true) {
                    if (!e.MoveNext()) throw Error.ArgumentOutOfRange("index");
                    if (index == 0) return e.Current;
                    index--;
                }
            }
        }
  
        public static TSource ElementAtOrDefault</tsource><tsource>(this IEnumerable</tsource><tsource> source, int index) {
            if (source == null) throw Error.ArgumentNull("source");
            if (index >= 0) {
                IList</tsource><tsource> list = source as IList</tsource><tsource>;
                if (list != null) {
                    if (index < list.Count) return list[index];
                }
                else {
                    using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                        while (true) {
                            if (!e.MoveNext()) break;
                            if (index == 0) return e.Current;
                            index--;
                        }
                    }
                }
            }
            return default(TSource);
        }
  
        public static IEnumerable</tsource><int> Range(int start, int count) {
            long max = ((long)start) + count - 1;
            if (count < 0 || max > Int32.MaxValue) throw Error.ArgumentOutOfRange("count");
            return RangeIterator(start, count);
        }
 
        static IEnumerable</int><int> RangeIterator(int start, int count) {
            for (int i = 0; i < count; i++) yield return start + i;
        }
  
        public static IEnumerable</int><tresult> Repeat</tresult><tresult>(TResult element, int count) {
            if (count < 0) throw Error.ArgumentOutOfRange("count");
            return RepeatIterator</tresult><tresult>(element, count);
        }
 
        static IEnumerable</tresult><tresult> RepeatIterator</tresult><tresult>(TResult element, int count) {
            for (int i = 0; i < count; i++) yield return element;
        }
  
        public static IEnumerable</tresult><tresult> Empty</tresult><tresult>() {
            return EmptyEnumerable</tresult><tresult>.Instance;
        }
 
        public static bool Any</tresult><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                if (e.MoveNext()) return true;
            }
            return false;
        }
 
        public static bool Any</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            foreach (TSource element in source) {
                if (predicate(element)) return true;
            }
            return false;
        }
 
        public static bool All</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            foreach (TSource element in source) {
                if (!predicate(element)) return false;
            }
            return true;
        }
 
        public static int Count</tsource,><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            ICollection</tsource><tsource> collectionoft = source as ICollection</tsource><tsource>;
            if (collectionoft != null) return collectionoft.Count;
            ICollection collection = source as ICollection;
            if (collection != null) return collection.Count;
            int count = 0;
            using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                checked {
                    while (e.MoveNext()) count++;
                }
            }
            return count;
        }
  
        public static int Count</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            int count = 0;
            foreach (TSource element in source) {
                checked {
                    if (predicate(element)) count++;
                }
            }
            return count;
        }
 
        public static long LongCount</tsource,><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            long count = 0;
            using (IEnumerator</tsource><tsource> e = source.GetEnumerator()) {
                checked {
                    while (e.MoveNext()) count++;
                }
            }
            return count;
        }
 
        public static long LongCount</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, bool=""> predicate) {
            if (source == null) throw Error.ArgumentNull("source");
            if (predicate == null) throw Error.ArgumentNull("predicate");
            long count = 0;
            foreach (TSource element in source) {
                checked {
                    if (predicate(element)) count++;
                }
            }
            return count;
        }
  
        public static bool Contains</tsource,><tsource>(this IEnumerable</tsource><tsource> source, TSource value) {
            ICollection</tsource><tsource> collection = source as ICollection</tsource><tsource>;
            if (collection != null) return collection.Contains(value);
            return Contains</tsource><tsource>(source, value, null);
        }
 
        public static bool Contains</tsource><tsource>(this IEnumerable</tsource><tsource> source, TSource value, IEqualityComparer</tsource><tsource> comparer)
        {
            if (comparer == null) comparer = EqualityComparer</tsource><tsource>.Default;
            if (source == null) throw Error.ArgumentNull("source");
            foreach (TSource element in source)
                if (comparer.Equals(element, value)) return true;
            return false;
        }
 
        public static TSource Aggregate</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, tsource,="" tsource=""> func)
        {
            if (source == null) throw Error.ArgumentNull("source");
            if (func == null) throw Error.ArgumentNull("func");
            using (IEnumerator</tsource,><tsource> e = source.GetEnumerator()) {
                if (!e.MoveNext()) throw Error.NoElements();
                TSource result = e.Current;
                while (e.MoveNext()) result = func(result, e.Current);
                return result;
            }
        }
  
        public static TAccumulate Aggregate</tsource><tsource, taccumulate="">(this IEnumerable</tsource,><tsource> source, TAccumulate seed, Func</tsource><taccumulate, tsource,="" taccumulate=""> func) {
            if (source == null) throw Error.ArgumentNull("source");
            if (func == null) throw Error.ArgumentNull("func");
            TAccumulate result = seed;
            foreach (TSource element in source) result = func(result, element);
            return result;
        }
 
        public static TResult Aggregate</taccumulate,><tsource, taccumulate,="" tresult="">(this IEnumerable</tsource,><tsource> source, TAccumulate seed, Func</tsource><taccumulate, tsource,="" taccumulate=""> func, Func</taccumulate,><taccumulate, tresult=""> resultSelector) {
            if (source == null) throw Error.ArgumentNull("source");
            if (func == null) throw Error.ArgumentNull("func");
            if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
            TAccumulate result = seed;
            foreach (TSource element in source) result = func(result, element);
            return resultSelector(result);
        }
 
        public static int Sum(this IEnumerable</taccumulate,><int> source) {
            if (source == null) throw Error.ArgumentNull("source");
            int sum = 0;
            checked {
                foreach (int v in source) sum += v;
            }
            return sum;
        }
 
        public static int? Sum(this IEnumerable</int><int?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            int sum = 0;
            checked {
                foreach (int? v in source) {
                    if (v != null) sum += v.GetValueOrDefault();
                }
            }
            return sum;
        }
  
        public static long Sum(this IEnumerable</int?><long> source) {
            if (source == null) throw Error.ArgumentNull("source");
            long sum = 0;
            checked {
                foreach (long v in source) sum += v;
            }
            return sum;
        }
  
        public static long? Sum(this IEnumerable</long><long?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            long sum = 0;
            checked {
                foreach (long? v in source) {
                    if (v != null) sum += v.GetValueOrDefault();
                }
            }
            return sum;
        }
  
        public static float Sum(this IEnumerable</long?><float> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double sum = 0;
            foreach (float v in source) sum += v;
            return (float)sum;
        }
  
        public static float? Sum(this IEnumerable</float><float?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double sum = 0;
            foreach (float? v in source) {
                if (v != null) sum += v.GetValueOrDefault();
            }
            return (float)sum;
        }
  
        public static double Sum(this IEnumerable</float?><double> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double sum = 0;
            foreach (double v in source) sum += v;
            return sum;
        }
 
        public static double? Sum(this IEnumerable</double><double?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double sum = 0;
            foreach (double? v in source) {
                if (v != null) sum += v.GetValueOrDefault();
            }
            return sum;
        }
 
        public static decimal Sum(this IEnumerable</double?><decimal> source) {
            if (source == null) throw Error.ArgumentNull("source");
            decimal sum = 0;
            foreach (decimal v in source) sum += v;
            return sum;
        }
 
        public static decimal? Sum(this IEnumerable</decimal><decimal?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            decimal sum = 0;
            foreach (decimal? v in source) {
                if (v != null) sum += v.GetValueOrDefault();
            }
            return sum;
        }
 
        public static int Sum</decimal?><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, int=""> selector) {
            return Enumerable.Sum(Enumerable.Select(source, selector));
        }
  
        public static int? Sum</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, int?=""> selector) {
            return Enumerable.Sum(Enumerable.Select(source, selector));
        }
 
        public static long Sum</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, long=""> selector) {
            return Enumerable.Sum(Enumerable.Select(source, selector));
        }
  
        public static long? Sum</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, long?=""> selector) {
            return Enumerable.Sum(Enumerable.Select(source, selector));
        }
 
        public static float Sum</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, float=""> selector) {
            return Enumerable.Sum(Enumerable.Select(source, selector));
        }
 
        public static float? Sum</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, float?=""> selector) {
            return Enumerable.Sum(Enumerable.Select(source, selector));
        }
  
        public static double Sum</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, double=""> selector) {
            return Enumerable.Sum(Enumerable.Select(source, selector));
        }
  
        public static double? Sum</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, double?=""> selector) {
            return Enumerable.Sum(Enumerable.Select(source, selector));
        }
 
        public static decimal Sum</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, decimal=""> selector) {
            return Enumerable.Sum(Enumerable.Select(source, selector));
        }
 
        public static decimal? Sum</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, decimal?=""> selector) {
            return Enumerable.Sum(Enumerable.Select(source, selector));
        }
  
        public static int Min(this IEnumerable</tsource,><int> source) {
            if (source == null) throw Error.ArgumentNull("source");
            int value = 0;
            bool hasValue = false;
            foreach (int x in source) {
                if (hasValue) {
                    if (x < value) value = x;
                }
                else {
                    value = x;
                    hasValue = true;
                }
            }
            if (hasValue) return value;
            throw Error.NoElements();
        }
  
        public static int? Min(this IEnumerable</int><int?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            int? value = null;
            foreach (int? x in source) {
                if (value == null || x < value)
                    value = x;
            }
            return value;
        }
  
        public static long Min(this IEnumerable</int?><long> source) {
            if (source == null) throw Error.ArgumentNull("source");
            long value = 0;
            bool hasValue = false;
            foreach (long x in source) {
                if (hasValue) {
                    if (x < value) value = x;
                }
                else {
                    value = x;
                    hasValue = true;
                }
            }
            if (hasValue) return value;
            throw Error.NoElements();
        }
  
        public static long? Min(this IEnumerable</long><long?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            long? value = null;
            foreach (long? x in source) {
                if (value == null || x < value) value = x;
            }
            return value;
        }
  
        public static float Min(this IEnumerable</long?><float> source) {
            if (source == null) throw Error.ArgumentNull("source");
            float value = 0;
            bool hasValue = false;
            foreach (float x in source) {
                if (hasValue) {
                    // Normally NaN < anything is false, as is anything < NaN
                    // However, this leads to some irksome outcomes in Min and Max.
                    // If we use those semantics then Min(NaN, 5.0) is NaN, but
                    // Min(5.0, NaN) is 5.0!  To fix this, we impose a total
                    // ordering where NaN is smaller than every value, including
                    // negative infinity.
                    if (x < value || System.Single.IsNaN(x)) value = x;
                }
                else {
                    value = x;
                    hasValue = true;
                }
            }
            if (hasValue) return value;
            throw Error.NoElements();
        }
 
        public static float? Min(this IEnumerable</float><float?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            float? value = null;
            foreach (float? x in source) {
                if (x == null) continue;
                if (value == null || x < value || System.Single.IsNaN((float)x)) value = x;
            }
            return value;
        }
 
        public static double Min(this IEnumerable</float?><double> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double value = 0;
            bool hasValue = false;
            foreach (double x in source) {
                if (hasValue) {
                    if (x < value || System.Double.IsNaN(x)) value = x;
                }
                else {
                    value = x;
                    hasValue = true;
                }
            }
            if (hasValue) return value;
            throw Error.NoElements();
        }
 
        public static double? Min(this IEnumerable</double><double?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double? value = null;
            foreach (double? x in source) {
                if (x == null) continue;
                if (value == null || x < value || System.Double.IsNaN((double)x)) value = x;
            }
            return value;
        }
 
        public static decimal Min(this IEnumerable</double?><decimal> source) {
            if (source == null) throw Error.ArgumentNull("source");
            decimal value = 0;
            bool hasValue = false;
            foreach (decimal x in source) {
                if (hasValue) {
                    if (x < value) value = x;
                }
                else {
                    value = x;
                    hasValue = true;
                }
            }
            if (hasValue) return value;
            throw Error.NoElements();
        }
 
        public static decimal? Min(this IEnumerable</decimal><decimal?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            decimal? value = null;
            foreach (decimal? x in source) {
                if (value == null || x < value) value = x;
            }
            return value;
        }
 
        public static TSource Min</decimal?><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            Comparer</tsource><tsource> comparer = Comparer</tsource><tsource>.Default;
            TSource value = default(TSource);
            if (value == null) {
                foreach (TSource x in source) {
                    if (x != null && (value == null || comparer.Compare(x, value) < 0))
                        value = x;
                }
                return value;
            }
            else {
                bool hasValue = false;
                foreach (TSource x in source) {
                    if (hasValue) {
                        if (comparer.Compare(x, value) < 0)
                            value = x;
                    }
                    else {
                        value = x;
                        hasValue = true;
                    }
                }
                if (hasValue) return value;
                throw Error.NoElements();
            }
        }
 
        public static int Min</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, int=""> selector) {
            return Enumerable.Min(Enumerable.Select(source, selector));
        }
  
        public static int? Min</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, int?=""> selector) {
            return Enumerable.Min(Enumerable.Select(source, selector));
        }
 
        public static long Min</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, long=""> selector) {
            return Enumerable.Min(Enumerable.Select(source, selector));
        }
  
        public static long? Min</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, long?=""> selector) {
            return Enumerable.Min(Enumerable.Select(source, selector));
        }
 
        public static float Min</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, float=""> selector) {
            return Enumerable.Min(Enumerable.Select(source, selector));
        }
 
        public static float? Min</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, float?=""> selector) {
            return Enumerable.Min(Enumerable.Select(source, selector));
        }
  
        public static double Min</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, double=""> selector) {
            return Enumerable.Min(Enumerable.Select(source, selector));
        }
  
        public static double? Min</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, double?=""> selector) {
            return Enumerable.Min(Enumerable.Select(source, selector));
        }
 
        public static decimal Min</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, decimal=""> selector) {
            return Enumerable.Min(Enumerable.Select(source, selector));
        }
 
        public static decimal? Min</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, decimal?=""> selector) {
            return Enumerable.Min(Enumerable.Select(source, selector));
        }
  
        public static TResult Min</tsource,><tsource, tresult="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tresult=""> selector) {
            return Enumerable.Min(Enumerable.Select(source, selector));
        }
 
        public static int Max(this IEnumerable</tsource,><int> source) {
            if (source == null) throw Error.ArgumentNull("source");
            int value = 0;
            bool hasValue = false;
            foreach (int x in source) {
                if (hasValue) {
                    if (x > value) value = x;
                }
                else {
                    value = x;
                    hasValue = true;
                }
            }
            if (hasValue) return value;
            throw Error.NoElements();
        }
 
        public static int? Max(this IEnumerable</int><int?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            int? value = null;
            foreach (int? x in source) {
                if (value == null || x > value) value = x;
            }
            return value;
        }
 
        public static long Max(this IEnumerable</int?><long> source) {
            if (source == null) throw Error.ArgumentNull("source");
            long value = 0;
            bool hasValue = false;
            foreach (long x in source) {
                if (hasValue) {
                    if (x > value) value = x;
                }
                else {
                    value = x;
                    hasValue = true;
                }
            }
            if (hasValue) return value;
            throw Error.NoElements();
        }
  
        public static long? Max(this IEnumerable</long><long?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            long? value = null;
            foreach (long? x in source) {
                if (value == null || x > value) value = x;
            }
            return value;
        }
  
        public static double Max(this IEnumerable</long?><double> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double value = 0;
            bool hasValue = false;
            foreach (double x in source) {
                if (hasValue) {
                    if (x > value || System.Double.IsNaN(value)) value = x;
                }
                else {
                    value = x;
                    hasValue = true;
                }
            }
            if (hasValue) return value;
            throw Error.NoElements();
        }
 
        public static double? Max(this IEnumerable</double><double?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double? value = null;
            foreach (double? x in source) {
                if (x == null) continue;
                if (value == null || x > value || System.Double.IsNaN((double)value)) value = x;
            }
            return value;
        }
  
        public static float Max(this IEnumerable</double?><float> source) {
            if (source == null) throw Error.ArgumentNull("source");
            float value = 0;
            bool hasValue = false;
            foreach (float x in source) {
                if (hasValue) {
                    if (x > value || System.Double.IsNaN(value)) value = x;
                }
                else {
                    value = x;
                    hasValue = true;
                }
            }
            if (hasValue) return value;
            throw Error.NoElements();
        }
 
        public static float? Max(this IEnumerable</float><float?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            float? value = null;
            foreach (float? x in source) {
                if (x == null) continue;
                if (value == null || x > value || System.Single.IsNaN((float)value)) value = x;
            }
            return value;
        }
  
        public static decimal Max(this IEnumerable</float?><decimal> source) {
            if (source == null) throw Error.ArgumentNull("source");
            decimal value = 0;
            bool hasValue = false;
            foreach (decimal x in source) {
                if (hasValue) {
                    if (x > value) value = x;
                }
                else {
                    value = x;
                    hasValue = true;
                }
            }
            if (hasValue) return value;
            throw Error.NoElements();
        }
 
        public static decimal? Max(this IEnumerable</decimal><decimal?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            decimal? value = null;
            foreach (decimal? x in source) {
                if (value == null || x > value) value = x;
            }
            return value;
        }
 
        public static TSource Max</decimal?><tsource>(this IEnumerable</tsource><tsource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            Comparer</tsource><tsource> comparer = Comparer</tsource><tsource>.Default;
            TSource value = default(TSource);
            if (value == null) {
                foreach (TSource x in source) {
                    if (x != null && (value == null || comparer.Compare(x, value) > 0))
                        value = x;
                }
                return value;
            }
            else {
                bool hasValue = false;
                foreach (TSource x in source) {
                    if (hasValue) {
                        if (comparer.Compare(x, value) > 0)
                            value = x;
                    }
                    else {
                        value = x;
                        hasValue = true;
                    }
                }
                if (hasValue) return value;
                throw Error.NoElements();
            }
        }
  
        public static int Max</tsource><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, int=""> selector) {
            return Enumerable.Max(Enumerable.Select(source, selector));
        }
  
        public static int? Max</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, int?=""> selector) {
            return Enumerable.Max(Enumerable.Select(source, selector));
        }
 
        public static long Max</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, long=""> selector) {
            return Enumerable.Max(Enumerable.Select(source, selector));
        }
 
        public static long? Max</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, long?=""> selector) {
            return Enumerable.Max(Enumerable.Select(source, selector));
        }
  
        public static float Max</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, float=""> selector) {
            return Enumerable.Max(Enumerable.Select(source, selector));
        }
 
        public static float? Max</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, float?=""> selector) {
            return Enumerable.Max(Enumerable.Select(source, selector));
        }
  
        public static double Max</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, double=""> selector) {
            return Enumerable.Max(Enumerable.Select(source, selector));
        }
 
        public static double? Max</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, double?=""> selector) {
            return Enumerable.Max(Enumerable.Select(source, selector));
        }
 
        public static decimal Max</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, decimal=""> selector) {
            return Enumerable.Max(Enumerable.Select(source, selector));
        }
  
        public static decimal? Max</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, decimal?=""> selector) {
            return Enumerable.Max(Enumerable.Select(source, selector));
        }
  
        public static TResult Max</tsource,><tsource, tresult="">(this IEnumerable</tsource,><tsource> source, Func</tsource><tsource, tresult=""> selector) {
            return Enumerable.Max(Enumerable.Select(source, selector));
        }
 
        public static double Average(this IEnumerable</tsource,><int> source) {
            if (source == null) throw Error.ArgumentNull("source");
            long sum = 0;
            long count = 0;
            checked {
                foreach (int v in source) {
                    sum += v;
                    count++;
                }
            }
            if (count > 0) return (double)sum / count;
            throw Error.NoElements();
        }
  
        public static double? Average(this IEnumerable</int><int?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            long sum = 0;
            long count = 0;
            checked {
                foreach (int? v in source) {
                    if (v != null) {
                        sum += v.GetValueOrDefault();
                        count++;
                    }
                }
            }
            if (count > 0) return (double)sum / count;
            return null;
        }
 
        public static double Average(this IEnumerable</int?><long> source) {
            if (source == null) throw Error.ArgumentNull("source");
            long sum = 0;
            long count = 0;
            checked {
                foreach (long v in source) {
                    sum += v;
                    count++;
                }
            }
            if (count > 0) return (double)sum / count;
            throw Error.NoElements();
        }
  
        public static double? Average(this IEnumerable</long><long?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            long sum = 0;
            long count = 0;
            checked {
                foreach (long? v in source) {
                    if (v != null) {
                        sum += v.GetValueOrDefault();
                        count++;
                    }
                }
            }
            if (count > 0) return (double)sum / count;
            return null;
        }
 
        public static float Average(this IEnumerable</long?><float> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double sum = 0;
            long count = 0;
            checked {
                foreach (float v in source) {
                    sum += v;
                    count++;
                }
            }
            if (count > 0) return (float)(sum / count);
            throw Error.NoElements();
        }
 
        public static float? Average(this IEnumerable</float><float?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double sum = 0;
            long count = 0;
            checked {
                foreach (float? v in source) {
                    if (v != null) {
                        sum += v.GetValueOrDefault();
                        count++;
                    }
                }
            }
            if (count > 0) return (float)(sum / count);
            return null;
        }
 
        public static double Average(this IEnumerable</float?><double> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double sum = 0;
            long count = 0;
            checked {
                foreach (double v in source) {
                    sum += v;
                    count++;
                }
            }
            if (count > 0) return sum / count;
            throw Error.NoElements();
        }
  
        public static double? Average(this IEnumerable</double><double?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            double sum = 0;
            long count = 0;
            checked {
                foreach (double? v in source) {
                    if (v != null) {
                        sum += v.GetValueOrDefault();
                        count++;
                    }
                }
            }
            if (count > 0) return sum / count;
            return null;
        }
 
        public static decimal Average(this IEnumerable</double?><decimal> source) {
            if (source == null) throw Error.ArgumentNull("source");
            decimal sum = 0;
            long count = 0;
            checked {
                foreach (decimal v in source) {
                    sum += v;
                    count++;
                }
            }
            if (count > 0) return sum / count;
            throw Error.NoElements();
        }
  
        public static decimal? Average(this IEnumerable</decimal><decimal?> source) {
            if (source == null) throw Error.ArgumentNull("source");
            decimal sum = 0;
            long count = 0;
            checked {
                foreach (decimal? v in source) {
                    if (v != null) {
                        sum += v.GetValueOrDefault();
                        count++;
                    }
                }
            }
            if (count > 0) return sum / count;
            return null;
        }
 
        public static double Average</decimal?><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, int=""> selector) {
            return Enumerable.Average(Enumerable.Select(source, selector));
        }
  
        public static double? Average</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, int?=""> selector) {
            return Enumerable.Average(Enumerable.Select(source, selector));
        }
  
        public static double Average</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, long=""> selector) {
            return Enumerable.Average(Enumerable.Select(source, selector));
        }
 
        public static double? Average</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, long?=""> selector) {
            return Enumerable.Average(Enumerable.Select(source, selector));
        }
 
        public static float Average</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, float=""> selector) {
            return Enumerable.Average(Enumerable.Select(source, selector));
        }
  
        public static float? Average</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, float?=""> selector) {
            return Enumerable.Average(Enumerable.Select(source, selector));
        }
 
        public static double Average</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, double=""> selector) {
            return Enumerable.Average(Enumerable.Select(source, selector));
        }
  
        public static double? Average</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, double?=""> selector) {
            return Enumerable.Average(Enumerable.Select(source, selector));
        }
 
        public static decimal Average</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, decimal=""> selector) {
            return Enumerable.Average(Enumerable.Select(source, selector));
        }
 
        public static decimal? Average</tsource,><tsource>(this IEnumerable</tsource><tsource> source, Func</tsource><tsource, decimal?=""> selector) {
            return Enumerable.Average(Enumerable.Select(source, selector));
        }
    }
 
    internal class EmptyEnumerable</tsource,><telement>
    {
        static TElement[] instance;
 
        public static IEnumerable</telement><telement> Instance {
            get {
                if (instance == null) instance = new TElement[0];
                return instance;
            }
        }
    }
  
    internal class IdentityFunction</telement><telement>
    {
        public static Func</telement><telement, telement=""> Instance {
            get { return x => x; }
        }
    }
 
    public interface IOrderedEnumerable</telement,><telement> : IEnumerable</telement><telement>
    {
        IOrderedEnumerable</telement><telement> CreateOrderedEnumerable</telement><tkey>(Func</tkey><telement, tkey=""> keySelector, IComparer</telement,><tkey> comparer, bool descending);
    }
  
#if SILVERLIGHT
    public interface IGrouping</tkey><tkey, telement=""> : IEnumerable</tkey,><telement>
#else
    public interface IGrouping</telement><out tkey,="" out="" telement=""> : IEnumerable</out><telement>
#endif
    {
        TKey Key { get; }
    }
  
    public interface ILookup</telement><tkey, telement=""> : IEnumerable</tkey,><igrouping<tkey, telement="">>{
        int Count { get; }
        IEnumerable</igrouping<tkey,><telement> this[TKey key] { get; }
        bool Contains(TKey key);
    }
  
    public class Lookup</telement><tkey, telement=""> : IEnumerable</tkey,><igrouping<tkey, telement="">>, ILookup</igrouping<tkey,><tkey, telement="">{
        IEqualityComparer</tkey,><tkey> comparer;
        Grouping[] groupings;
        Grouping lastGrouping;
        int count;
 
        internal static Lookup</tkey><tkey, telement=""> Create</tkey,><tsource>(IEnumerable</tsource><tsource> source, Func</tsource><tsource, tkey=""> keySelector, Func</tsource,><tsource, telement=""> elementSelector, IEqualityComparer</tsource,><tkey> comparer) {
            if (source == null) throw Error.ArgumentNull("source");
            if (keySelector == null) throw Error.ArgumentNull("keySelector");
            if (elementSelector == null) throw Error.ArgumentNull("elementSelector");
            Lookup</tkey><tkey, telement=""> lookup = new Lookup</tkey,><tkey, telement="">(comparer);
            foreach (TSource item in source) {
                lookup.GetGrouping(keySelector(item), true).Add(elementSelector(item));
            }
            return lookup;
        }
 
        internal static Lookup</tkey,><tkey, telement=""> CreateForJoin(IEnumerable</tkey,><telement> source, Func</telement><telement, tkey=""> keySelector, IEqualityComparer</telement,><tkey> comparer) {
            Lookup</tkey><tkey, telement=""> lookup = new Lookup</tkey,><tkey, telement="">(comparer);
            foreach (TElement item in source) {
                TKey key = keySelector(item);
                if (key != null) lookup.GetGrouping(key, true).Add(item);
            }
            return lookup;
        }
 
        Lookup(IEqualityComparer</tkey,><tkey> comparer) {
            if (comparer == null) comparer = EqualityComparer</tkey><tkey>.Default;
            this.comparer = comparer;
            groupings = new Grouping[7];
        }
  
        public int Count {
            get { return count; }
        }
  
        public IEnumerable</tkey><telement> this[TKey key] {
            get {
                Grouping grouping = GetGrouping(key, false);
                if (grouping != null) return grouping;
                return EmptyEnumerable</telement><telement>.Instance;
            }
        }
 
        public bool Contains(TKey key) {
            return GetGrouping(key, false) != null;
        }
  
        public IEnumerator</telement><igrouping<tkey, telement="">> GetEnumerator() {
            Grouping g = lastGrouping;
            if (g != null) {
                do {
                    g = g.next;
                    yield return g;
                } while (g != lastGrouping);
            }
        }
 
        public IEnumerable</igrouping<tkey,><tresult> ApplyResultSelector</tresult><tresult>(Func</tresult><tkey, ienumerable<telement="">, TResult> resultSelector){
            Grouping g = lastGrouping;
            if (g != null) {
                do {
                    g = g.next;
                    if (g.count != g.elements.Length) { Array.Resize</tkey,><telement>(ref g.elements, g.count); }
                    yield return resultSelector(g.key, g.elements);
                }while (g != lastGrouping);
            }
        }
 
        IEnumerator IEnumerable.GetEnumerator() {
            return GetEnumerator();
        }
 
        internal int InternalGetHashCode(TKey key)
        {
            //[....] DevDivBugs 171937. work around comparer implementations that throw when passed null
            return (key == null) ? 0 : comparer.GetHashCode(key) & 0x7FFFFFFF;
        }
 
        internal Grouping GetGrouping(TKey key, bool create) {
            int hashCode = InternalGetHashCode(key);
            for (Grouping g = groupings[hashCode % groupings.Length]; g != null; g = g.hashNext)
                if (g.hashCode == hashCode && comparer.Equals(g.key, key)) return g;
            if (create) {
                if (count == groupings.Length) Resize();
                int index = hashCode % groupings.Length;
                Grouping g = new Grouping();
                g.key = key;
                g.hashCode = hashCode;
                g.elements = new TElement[1];
                g.hashNext = groupings[index];
                groupings[index] = g;
                if (lastGrouping == null) {
                    g.next = g;
                }
                else {
                    g.next = lastGrouping.next;
                    lastGrouping.next = g;
                }
                lastGrouping = g;
                count++;
                return g;
            }
            return null;
        }
 
        void Resize() {
            int newSize = checked(count * 2 + 1);
            Grouping[] newGroupings = new Grouping[newSize];
            Grouping g = lastGrouping;
            do {
                g = g.next;
                int index = g.hashCode % newSize;
                g.hashNext = newGroupings[index];
                newGroupings[index] = g;
            } while (g != lastGrouping);
            groupings = newGroupings;
        }
  
        internal class Grouping : IGrouping</telement><tkey, telement="">, IList</tkey,><telement>
        {
            internal TKey key;
            internal int hashCode;
            internal TElement[] elements;
            internal int count;
            internal Grouping hashNext;
            internal Grouping next;
  
            internal void Add(TElement element) {
                if (elements.Length == count) Array.Resize(ref elements, checked(count * 2));
                elements[count] = element;
                count++;
            }
 
            public IEnumerator</telement><telement> GetEnumerator() {
                for (int i = 0; i < count; i++) yield return elements[i];
            }
  
            IEnumerator IEnumerable.GetEnumerator() {
                return GetEnumerator();
            }
 
            // DDB195907: implement IGrouping<>.Key implicitly
            // so that WPF binding works on this property.
            public TKey Key {
                get { return key; }
            }
 
            int ICollection</telement><telement>.Count {
                get { return count; }
            }
 
            bool ICollection</telement><telement>.IsReadOnly {
                get { return true; }
            }
  
            void ICollection</telement><telement>.Add(TElement item) {
                throw Error.NotSupported();
            }
 
            void ICollection</telement><telement>.Clear() {
                throw Error.NotSupported();
            }
  
            bool ICollection</telement><telement>.Contains(TElement item) {
                return Array.IndexOf(elements, item, 0, count) >= 0;
            }
 
            void ICollection</telement><telement>.CopyTo(TElement[] array, int arrayIndex) {
                Array.Copy(elements, 0, array, arrayIndex, count);
            }
 
            bool ICollection</telement><telement>.Remove(TElement item) {
                throw Error.NotSupported();
            }
  
            int IList</telement><telement>.IndexOf(TElement item) {
                return Array.IndexOf(elements, item, 0, count);
            }
  
            void IList</telement><telement>.Insert(int index, TElement item) {
                throw Error.NotSupported();
            }
 
            void IList</telement><telement>.RemoveAt(int index) {
                throw Error.NotSupported();
            }
 
            TElement IList</telement><telement>.this[int index] {
                get {
                    if (index < 0 || index >= count) throw Error.ArgumentOutOfRange("index");
                    return elements[index];
                }
                set {
                    throw Error.NotSupported();
                }
            }
        }
    }
  
    internal class Set</telement><telement>
    {
        int[] buckets;
        Slot[] slots;
        int count;
        int freeList;
        IEqualityComparer</telement><telement> comparer;
 
        public Set() : this(null) { }
  
        public Set(IEqualityComparer</telement><telement> comparer) {
            if (comparer == null) comparer = EqualityComparer</telement><telement>.Default;
            this.comparer = comparer;
            buckets = new int[7];
            slots = new Slot[7];
            freeList = -1;
        }
  
        // If value is not in set, add it and return true; otherwise return false
        public bool Add(TElement value) {
            return !Find(value, true);
        }
 
        // Check whether value is in set
        public bool Contains(TElement value) {
            return Find(value, false);
        }
  
        // If value is in set, remove it and return true; otherwise return false
        public bool Remove(TElement value) {
            int hashCode = InternalGetHashCode(value);
            int bucket = hashCode % buckets.Length;
            int last = -1;
            for (int i = buckets[bucket] - 1; i >= 0; last = i, i = slots[i].next) {
                if (slots[i].hashCode == hashCode && comparer.Equals(slots[i].value, value)) {
                    if (last < 0) {
                        buckets[bucket] = slots[i].next + 1;
                    }
                    else {
                        slots[last].next = slots[i].next;
                    }
                    slots[i].hashCode = -1;
                    slots[i].value = default(TElement);
                    slots[i].next = freeList;
                    freeList = i;
                    return true;
                }
            }
            return false;
        }
 
        bool Find(TElement value, bool add) {
            int hashCode = InternalGetHashCode(value);
            for (int i = buckets[hashCode % buckets.Length] - 1; i >= 0; i = slots[i].next) {
                if (slots[i].hashCode == hashCode && comparer.Equals(slots[i].value, value)) return true;
            }
            if (add) {
                int index;
                if (freeList >= 0) {
                    index = freeList;
                    freeList = slots[index].next;
                }
                else {
                    if (count == slots.Length) Resize();
                    index = count;
                    count++;
                }
                int bucket = hashCode % buckets.Length;
                slots[index].hashCode = hashCode;
                slots[index].value = value;
                slots[index].next = buckets[bucket] - 1;
                buckets[bucket] = index + 1;
            }
            return false;
        }
 
        void Resize() {
            int newSize = checked(count * 2 + 1);
            int[] newBuckets = new int[newSize];
            Slot[] newSlots = new Slot[newSize];
            Array.Copy(slots, 0, newSlots, 0, count);
            for (int i = 0; i < count; i++) {
                int bucket = newSlots[i].hashCode % newSize;
                newSlots[i].next = newBuckets[bucket] - 1;
                newBuckets[bucket] = i + 1;
            }
            buckets = newBuckets;
            slots = newSlots;
        }
  
        internal int InternalGetHashCode(TElement value)
        {
            //[....] DevDivBugs 171937. work around comparer implementations that throw when passed null
            return (value == null) ? 0 : comparer.GetHashCode(value) & 0x7FFFFFFF;
        }
 
        internal struct Slot
        {
            internal int hashCode;
            internal TElement value;
            internal int next;
        }
    }
 
    internal class GroupedEnumerable</telement><tsource, tkey,="" telement,="" tresult=""> : IEnumerable</tsource,><tresult>{
        IEnumerable</tresult><tsource> source;
        Func</tsource><tsource, tkey=""> keySelector;
        Func</tsource,><tsource, telement=""> elementSelector;
        IEqualityComparer</tsource,><tkey> comparer;
        Func</tkey><tkey, ienumerable<telement="">, TResult> resultSelector;
  
        public GroupedEnumerable(IEnumerable</tkey,><tsource> source, Func</tsource><tsource, tkey=""> keySelector, Func</tsource,><tsource, telement=""> elementSelector, Func</tsource,><tkey, ienumerable<telement="">, TResult> resultSelector, IEqualityComparer</tkey,><tkey> comparer){
            if (source == null) throw Error.ArgumentNull("source");
            if (keySelector == null) throw Error.ArgumentNull("keySelector");
            if (elementSelector == null) throw Error.ArgumentNull("elementSelector");
            if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
            this.source = source;
            this.keySelector = keySelector;
            this.elementSelector = elementSelector;
            this.comparer = comparer;
            this.resultSelector = resultSelector;
        }
 
        public IEnumerator</tkey><tresult> GetEnumerator(){
            Lookup</tresult><tkey, telement=""> lookup = Lookup</tkey,><tkey, telement="">.Create</tkey,><tsource>(source, keySelector, elementSelector, comparer);
            return lookup.ApplyResultSelector(resultSelector).GetEnumerator();
        }
 
        IEnumerator IEnumerable.GetEnumerator(){
            return GetEnumerator();
        }
    }
  
    internal class GroupedEnumerable</tsource><tsource, tkey,="" telement=""> : IEnumerable</tsource,><igrouping<tkey, telement="">>
    {
        IEnumerable</igrouping<tkey,><tsource> source;
        Func</tsource><tsource, tkey=""> keySelector;
        Func</tsource,><tsource, telement=""> elementSelector;
        IEqualityComparer</tsource,><tkey> comparer;
 
        public GroupedEnumerable(IEnumerable</tkey><tsource> source, Func</tsource><tsource, tkey=""> keySelector, Func</tsource,><tsource, telement=""> elementSelector, IEqualityComparer</tsource,><tkey> comparer) {
            if (source == null) throw Error.ArgumentNull("source");
            if (keySelector == null) throw Error.ArgumentNull("keySelector");
            if (elementSelector == null) throw Error.ArgumentNull("elementSelector");
            this.source = source;
            this.keySelector = keySelector;
            this.elementSelector = elementSelector;
            this.comparer = comparer;
        }
 
        public IEnumerator</tkey><igrouping<tkey, telement="">> GetEnumerator() {
            return Lookup</igrouping<tkey,><tkey, telement="">.Create</tkey,><tsource>(source, keySelector, elementSelector, comparer).GetEnumerator();
        }
  
        IEnumerator IEnumerable.GetEnumerator() {
            return GetEnumerator();
        }
    }
 
    internal abstract class OrderedEnumerable</tsource><telement> : IOrderedEnumerable</telement><telement>
    {
        internal IEnumerable</telement><telement> source;
  
        public IEnumerator</telement><telement> GetEnumerator() {
            Buffer</telement><telement> buffer = new Buffer</telement><telement>(source);
            if (buffer.count > 0) {
                EnumerableSorter</telement><telement> sorter = GetEnumerableSorter(null);
                int[] map = sorter.Sort(buffer.items, buffer.count);
                sorter = null;
                for (int i = 0; i < buffer.count; i++) yield return buffer.items[map[i]];
            }
        }
 
        internal abstract EnumerableSorter</telement><telement> GetEnumerableSorter(EnumerableSorter</telement><telement> next);
 
        IEnumerator IEnumerable.GetEnumerator() {
            return GetEnumerator();
        }
 
        IOrderedEnumerable</telement><telement> IOrderedEnumerable</telement><telement>.CreateOrderedEnumerable</telement><tkey>(Func</tkey><telement, tkey=""> keySelector, IComparer</telement,><tkey> comparer, bool descending) {
            OrderedEnumerable</tkey><telement, tkey=""> result = new OrderedEnumerable</telement,><telement, tkey="">(source, keySelector, comparer, descending);
            result.parent = this;
            return result;
        }
    }
 
    internal class OrderedEnumerable</telement,><telement, tkey=""> : OrderedEnumerable</telement,><telement>
    {
        internal OrderedEnumerable</telement><telement> parent;
        internal Func</telement><telement, tkey=""> keySelector;
        internal IComparer</telement,><tkey> comparer;
        internal bool descending;
 
        internal OrderedEnumerable(IEnumerable</tkey><telement> source, Func</telement><telement, tkey=""> keySelector, IComparer</telement,><tkey> comparer, bool descending) {
            if (source == null) throw Error.ArgumentNull("source");
            if (keySelector == null) throw Error.ArgumentNull("keySelector");
            this.source = source;
            this.parent = null;
            this.keySelector = keySelector;
            this.comparer = comparer != null ? comparer : Comparer</tkey><tkey>.Default;
            this.descending = descending;
        }
 
        internal override EnumerableSorter</tkey><telement> GetEnumerableSorter(EnumerableSorter</telement><telement> next) {
            EnumerableSorter</telement><telement> sorter = new EnumerableSorter</telement><telement, tkey="">(keySelector, comparer, descending, next);
            if (parent != null) sorter = parent.GetEnumerableSorter(sorter);
            return sorter;
        }
    }
  
    internal abstract class EnumerableSorter</telement,><telement>
    {
        internal abstract void ComputeKeys(TElement[] elements, int count);
  
        internal abstract int CompareKeys(int index1, int index2);
  
        internal int[] Sort(TElement[] elements, int count) {
            ComputeKeys(elements, count);
            int[] map = new int[count];
            for (int i = 0; i < count; i++) map[i] = i;
            QuickSort(map, 0, count - 1);
            return map;
        }
 
        void QuickSort(int[] map, int left, int right) {
            do {
                int i = left;
                int j = right;
                int x = map[i + ((j - i) >> 1)];
                do {
                    while (i < map.Length && CompareKeys(x, map[i]) > 0) i++;
                    while (j >= 0 && CompareKeys(x, map[j]) < 0) j--;
                    if (i > j) break;
                    if (i < j) {
                        int temp = map[i];
                        map[i] = map[j];
                        map[j] = temp;
                    }
                    i++;
                    j--;
                } while (i <= j);
                if (j - left <= right - i) {
                    if (left < j) QuickSort(map, left, j);
                    left = i;
                }
                else {
                    if (i < right) QuickSort(map, i, right);
                    right = j;
                }
            } while (left < right);
        }
    }
  
    internal class EnumerableSorter</telement><telement, tkey=""> : EnumerableSorter</telement,><telement>
    {
        internal Func</telement><telement, tkey=""> keySelector;
        internal IComparer</telement,><tkey> comparer;
        internal bool descending;
        internal EnumerableSorter</tkey><telement> next;
        internal TKey[] keys;
  
        internal EnumerableSorter(Func</telement><telement, tkey=""> keySelector, IComparer</telement,><tkey> comparer, bool descending, EnumerableSorter</tkey><telement> next) {
            this.keySelector = keySelector;
            this.comparer = comparer;
            this.descending = descending;
            this.next = next;
        }
  
        internal override void ComputeKeys(TElement[] elements, int count) {
            keys = new TKey[count];
            for (int i = 0; i < count; i++) keys[i] = keySelector(elements[i]);
            if (next != null) next.ComputeKeys(elements, count);
        }
 
        internal override int CompareKeys(int index1, int index2) {
            int c = comparer.Compare(keys[index1], keys[index2]);
            if (c == 0) {
                if (next == null) return index1 - index2;
                return next.CompareKeys(index1, index2);
            }
            return descending ? -c : c;
        }
    }
 
    struct Buffer</telement><telement>
    {
        internal TElement[] items;
        internal int count;
  
        internal Buffer(IEnumerable</telement><telement> source) {
            TElement[] items = null;
            int count = 0;
            ICollection</telement><telement> collection = source as ICollection</telement><telement>;
            if (collection != null) {
                count = collection.Count;
                if (count > 0) {
                    items = new TElement[count];
                    collection.CopyTo(items, 0);
                }
            }
            else {
                foreach (TElement item in source) {
                    if (items == null) {
                        items = new TElement[4];
                    }
                    else if (items.Length == count) {
                        TElement[] newItems = new TElement[checked(count * 2)];
                        Array.Copy(items, 0, newItems, 0, count);
                        items = newItems;
                    }
                    items[count] = item;
                    count++;
                }
            }
            this.items = items;
            this.count = count;
        }
  
        internal TElement[] ToArray() {
            if (count == 0) return new TElement[0];
            if (items.Length == count) return items;
            TElement[] result = new TElement[count];
            Array.Copy(items, 0, result, 0, count);
            return result;
        }
    }
  
    ///
    /// 
    internal sealed class SystemCore_EnumerableDebugView</telement><summary>
    /// This class provides the items view for the Enumerable
    /// </summary><typeparam name="T"></typeparam><t>
    {
        public SystemCore_EnumerableDebugView(IEnumerable</t><t> enumerable)
        {
            if (enumerable == null)
            {
                throw new ArgumentNullException("enumerable");
            }
  
            this.enumerable = enumerable;
        }
  
        [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)]
        public T[] Items
        {
            get
            {
                List</t><t> tempList = new List</t><t>();
                IEnumerator</t><t> currentEnumerator = this.enumerable.GetEnumerator();
  
                if (currentEnumerator != null)
                {
                    for(count = 0; currentEnumerator.MoveNext(); count++)
                    {
                        tempList.Add(currentEnumerator.Current);
                    }
                }
                if (count == 0)
                {
                    throw new SystemCore_EnumerableDebugViewEmptyException();
                }
                cachedCollection = new T[this.count];
                tempList.CopyTo(cachedCollection, 0);
                return cachedCollection;
            }
        }
 
        [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
        private IEnumerable</t><t> enumerable;
 
        [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
        private T[] cachedCollection;
 
        [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
        private int count;
    }
  
    internal sealed class SystemCore_EnumerableDebugViewEmptyException : Exception
    {
        public string Empty
        {
            get
            {
                return Strings.EmptyEnumerable;
            }
        }
    }
 
    internal sealed class SystemCore_EnumerableDebugView
    {
        public SystemCore_EnumerableDebugView(IEnumerable enumerable)
        {
            if (enumerable == null)
            {
                throw new ArgumentNullException("enumerable");
            }
 
            this.enumerable = enumerable;
            count = 0;
            cachedCollection = null;
        }
  
        [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)]
        public object[] Items
        {
            get
            {
                List</t><object> tempList = new List</object><object>();
                IEnumerator currentEnumerator = this.enumerable.GetEnumerator();
 
                if (currentEnumerator != null)
                {
                    for (count = 0; currentEnumerator.MoveNext(); count++)
                    {
                        tempList.Add(currentEnumerator.Current);
                    }
                }
                if (count == 0)
                {
                    throw new SystemCore_EnumerableDebugViewEmptyException();
                }
                cachedCollection = new object[this.count];
                tempList.CopyTo(cachedCollection, 0);
                return cachedCollection;
            }
        }
 
        [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
        private IEnumerable enumerable;
 
        [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
        private object[] cachedCollection;
 
        [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
        private int count;
    }
}
 
